专栏文章

题解:CF1172F Nauuo and Bug

CF1172F题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mip8e76n
此快照首次捕获于
2025/12/03 07:50
3 个月前
此快照最后确认于
2025/12/03 07:50
3 个月前
查看原文

思路

扫描线,扫到一个左端点就向平衡树插入一个 00,记录下这个节点的编号。
每扫过一个 ii 就按 pai1p-a_i-1 分成两棵子树 x,yx,y
xx 全部加上 aia_iyy 全部加上 aipa_i-p
x,yx,y 合并起来,值域有交,采用一段一段合并的方式。
扫到右端点,取出对应编号的值,注意要加上根节点到这个节点的懒标记。

代码

CPP
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define debug(x) cerr<<#x<<':'<<x<<endl
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const int N=1e6+5;
int n,m,mod;
int a[N];
int id[N];
int val[N],tag[N],fa[N],lc[N],rc[N],key[N];
int tot,root;
int ans[N];
vector<int> L[N],R[N];
mt19937 rnd(time(0));
inline int new_node(int x){
    tot++;
    val[tot]=x,key[tot]=rnd();
    return tot;
}
inline void push_up(int p){
    fa[p]=0;
    if(lc[p]) fa[lc[p]]=p;
    if(rc[p]) fa[rc[p]]=p;
}
inline void push_down(int p){
    if(!tag[p]) return;
    if(lc[p]) val[lc[p]]+=tag[p],tag[lc[p]]+=tag[p];
    if(rc[p]) val[rc[p]]+=tag[p],tag[rc[p]]+=tag[p];
    tag[p]=0;
}
void split(int p,int k,int &x,int &y){
    if(!p) return x=y=0,void();
    push_down(p);
    if(val[p]<=k){
        x=p;
        split(rc[p],k,rc[x],y);
        push_up(x);
    }
    else{
        y=p;
        split(lc[p],k,x,lc[y]);
        push_up(y);
    }
}
int merge(int x,int y){
    if(!x||!y) return x|y;
    push_down(x),push_down(y);
    if(key[x]>key[y]){
        rc[x]=merge(rc[x],y);
        push_up(x);
        return x;
    }
    else{
        lc[y]=merge(x,lc[y]);
        push_up(y);
        return y;
    }
}
inline int ins(int x){
    int a,b;
    split(root,x,a,b);
    int p=new_node(x);
    root=merge(a,merge(p,b));
    return p;
}
int mi(int x){
    while(lc[x]) push_down(x),x=lc[x];
    return val[x];
}
inline void change(int x){
    int a,b;
    split(root,mod-x-1,a,b);
    if(a) val[a]+=x,tag[a]+=x;
    if(b) val[b]+=x-mod,tag[b]+=x-mod;
    root=0;
    if(mi(a)>mi(b)) swap(a,b);
    while(b){
        int u,v;
        split(a,mi(b),u,v);
        root=merge(root,u);
        a=v,swap(a,b);
    }
    root=merge(root,a);
}
inline int query(int x){
    int res=val[x];
    while(fa[x]) x=fa[x],res+=tag[x];
    return res;
}
signed main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    IOS;
    cin>>n>>m>>mod;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1,l,r;i<=m;i++){
        cin>>l>>r;
        L[l].push_back(i),R[r].push_back(i);
    }
    for(int i=1;i<=n;i++){
        for(int x:L[i]) id[x]=ins(0);
        change(a[i]);
        for(int x:R[i]) ans[x]=query(id[x]);
    }
    for(int i=1;i<=m;i++) cout<<ans[i]<<endl;
    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...