首页 > 其他分享 >关于此题[ABC389F] Rated Range 线段树二分的一些总结

关于此题[ABC389F] Rated Range 线段树二分的一些总结

时间:2025-01-22 13:09:34浏览次数:1  
标签:Rated mid long ABC389F Range maxn 区间 query minv

传送门

题目大意

  • 依次给定\(n\)个区间,并给定\(q\)个数,每个数依次经过这些区间时若在区间中则加1,问最后每个数变成了多少。

做法

  • 显然如果直接模拟的话时间复杂度肯定是会炸的。
  • 首先我们注意到这道题是可以离线处理的,并且对于所有询问的数,我们如果先对他们排好序,在每个数都各自依次经过所给的区间之后,最后的序列依然是非递减的(可以自己试着感性证明一下),于是问题就变成了:依次对于所给的区间,在一个有序的数列当中找到所有属于这个区间的数,并使他们加1。而所有属于这个区间的数在这个数列中一定是连续的(因为这个数列是非递减的),那么就引申出了做法。
  • 首先提供一种树状数组的思路,我们可以用二分来找到当前这个数列中第一个小于当前区间左端点\(l[i]\)的数的位置第一个大于当前区间右端点\(r[i]\)的数的位置,然后利用差分进行每次的修改。由于在二分的过程中对于每个数的判断都需要树状数组求差分前缀和,所以时间复杂度是\(O(nlog^{2}n)\)的。
  • 再给出一种线段树二分的做法。我们可以利用线段树来维护所给的询问排好序后的数列中最小值和最大值,在每次区间修改操作时,对于当前区间,如果当前区间最小值不比\(l[i]\)小,最大值不比\(r[i]\)大,那么当前区间肯定是需要直接全部加1的。而对于其他情况,线段树中当前区间的左儿子区间的数一定是比右儿子区间的数小的,所以如果\(l[i]\)比左儿子区间的最大值小那么说明左儿子区间存在需要修改的值,如果\(r[i]\)比右儿子区间的最小值大那么说明右儿子区间存在需要修改的值,再往后递归即可。
  • 最后就是数组一定不要开小了

代码

#include<bits/stdc++.h>
    
using namespace std;

long long t;
const long long N = 5e5 + 10;
long long n,q;
long long l[N],r[N],add[3000010],minv[3000010],maxn[3000010];
long long ans[600010],p[3000010];
struct node {
    long long num,pos;
    bool operator < (const node &a) const {
        return num < a.num;
    }
}query[600010];

void build(long long k,long long l,long long r) {
    if(l == r) {
        minv[k] = maxn[k] = query[l].num;
        p[k] = query[l].pos;
        return;
    }
    long long mid = (l + r) >> 1;
    build(k * 2,l,mid);
    build(k * 2 + 1,mid + 1,r);
    minv[k] = min(minv[k * 2],minv[k * 2 + 1]);
    maxn[k] = max(maxn[k * 2],maxn[k * 2 + 1]);
}

void Add(long long k,long long l,long long r,long long v) {
    minv[k] += v;
    maxn[k] += v;
    add[k] += v;
}

void pushdown(long long k,long long l,long long r,long long mid) {
    Add(k * 2,l,mid,add[k]);
    Add(k * 2 + 1,mid + 1,r,add[k]);
    add[k] = 0;
}

void modify(long long k,long long l,long long r,long long x,long long y) {
    if(l == r) {
        if(minv[k] >= x && maxn[k] <= y) minv[k]++,maxn[k]++;
        return;
    }
    if(x <= minv[k] && maxn[k] <= y) {
        minv[k]++;
        maxn[k]++;
        add[k]++;
        return ;
    }
    long long mid = (l + r) >> 1;
    pushdown(k,l,r,mid);
    if(x <= maxn[k * 2]) modify(k * 2,l,mid,x,y);
    if(y >= minv[k * 2 + 1]) modify(k * 2 + 1,mid + 1,r,x,y);
    minv[k] = min(minv[k * 2],minv[k * 2 + 1]);
    maxn[k] = max(maxn[k * 2],maxn[k * 2 + 1]);
}

void rbuild(long long k,long long l,long long r) {
    if(l == r) {
        ans[p[k]] = maxn[k];
        return;
    }
    long long mid = (l + r) >> 1;
    pushdown(k,l,r,mid);
    rbuild(k * 2,l,mid);
    rbuild(k * 2 + 1,mid + 1,r);
}
    
void solve() {
    cin >> n;
    for(long long i = 1;i <= n;i++) cin >> l[i] >> r[i];
    cin >> q;
    for(long long i = 1;i <= q;i++) {
        cin >> query[i].num;
        query[i].pos = i;
    }
    sort(query+1,query+1+q);
    build(1,1,q);
    for(long long i = 1;i <= n;i++)
        modify(1,1,q,l[i],r[i]);
    rbuild(1,1,q);
    for(long long i = 1;i <= q;i++) cout << ans[i] << '\n';
}
    
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    t = 1;
    while(t--) solve();
    
    return 0;
}

标签:Rated,mid,long,ABC389F,Range,maxn,区间,query,minv
From: https://www.cnblogs.com/lwiwi/p/18685602

相关文章

  • AT_abc389_f [ABC389F] Rated Range 题解
    题目传送门前置知识Treap|线段树解法考虑将询问的\(x\)离线下来在升序排序后一起处理。观察到每次操作只有\(+1\),即其之间的相对大小关系不会发生变化,此时就只需要支持将值在\([l,r]\)内的数加一,可以记录懒惰标记。线段树上二分找到端点或直接FHQ-Treap分裂出合法......
  • 「C/C++」C++20 标准库之#include <ranges>范围库
    ✨博客主页何曾参静谧的博客(✅关注、......
  • 实施零信任模型的方法指南 支柱1用户 集成ICAM平台(Integrated ICAM Platform)
    1.9.1功能描述国防部各组织和整个企业采用企业级身份管理和公钥基础设施(PKI)系统,用于跟踪整个网络中的用户、管理员和非人员实体(NPE)的身份,并确保访问权限仅限于有需要且有知情权的人员,各组织可以通过凭证管理系统、身份治理和管理工具以及访问管理工具来验证其是否为必需......
  • Educational Codeforces Round 149 (Rated for Div. 2) / 1837
    A.GrasshopperonaLine难度(个人感觉)☆☆☆☆☆Codeif(L%k==0){ans.push_back(1);ans.push_back(L-1);}else{ans.push_back(L);}B.ComparisonString难度(个人感觉)★☆☆☆☆思考:注意到最长链(指一些连续的位置,它们是单调的)是答案的下界,而实际上这是下......
  • Educational Codeforces Round 146 (Rated for Div. 2) / 1814
    A.Coins难度(个人感觉)☆☆☆☆☆思考:关键是2可以凑出任意偶数Code:if(n%2==0){ok=1;}else{if(k%2==0){ok=0;}else{ok=n>=k;}}B.LongLegs难度(个人感觉)★☆☆☆☆思考:当最终\(m=1e5\),答案不超过\(3e5\),因此最优的情况......
  • 音视频文件提供流式传输之HTTP Range 请求
    在Web开发中,正确返回音频和视频流给前端的方式是确保服务器端以流的形式发送媒体文件,而不是将整个文件加载到内存中,然后再传输。这种做法可以提高性能,避免内存溢出,尤其是在处理大文件时。对于音频和视频流的处理,最常见的技术是HTTP流式传输(HTTPStreaming)Range请求。这些......
  • VP Educational Codeforces Round 159 (Rated for Div. 2)
    A.BinaryImbalance题意:给你一个01串,每次选一个01或者一个10在他们中间插一个0进去,问能不能让0的个数大于1。我们进行一次插入操作后,显然还可以继续操作,所以只要有0和1就一定可以。注意特判全0的情况。点击查看代码voidsolve(){ intn; std::cin>>n; std::s......
  • 【Unity 编辑器插件】Stranger Lands - StampIT! 旨在简化和加速游戏场景构建中的地形
    StrangerLands-StampIT!是一款Unity插件,专为游戏开发者设计,旨在简化和加速游戏场景构建中的地形、地图和环境资源布局。它特别适用于需要大规模、快速生成或修改地形的项目,如开放世界、冒险类游戏、沙盒游戏等。通过该插件,开发者可以通过简单的操作快速“印刷”出各种地形......
  • HTTP 范围Range请求
    引言在现代Web应用中,HTTP范围请求是一种重要的技术,允许客户端请求资源的部分内容,而不是整个资源。这对于大型文件的传输尤其有用,如视频流、断点续传下载等。本文将深入探讨HTTP范围请求的工作原理、实现方法和应用场景。HTTP范围请求的基本概念HTTP范围请求通过 Range头部字段......
  • CodeTON Round 6 (Div. 1 + Div. 2, Rated, Prizes!) B. Friendly Arrays
    Codeforces题解-[B.FriendlyArrays]题目链接题目描述Youaregiventwoarraysofintegers—\(a_1,\ldots,a_n\)oflength\(n\),and\(b_1,\ldots,b_m\)oflength\(m\).Youcanchooseanyelement\(b_j\)fromarray\(b\)(\(1\leqj\leqm......