线段树分裂,WA 80pts,求调
查看原帖
线段树分裂,WA 80pts,求调
633466
LiaoYF1楼主2024/8/28 17:38
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
using namespace std;
#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) 42
#endif
const int INF=1e18;
const int N=100005;
const int MOD=1e9+7;
struct segtree{
    struct node{
        int l,r,val;
    }tr[50*N];
    int tot;
    void pushup(int p){
        tr[p].val=tr[tr[p].l].val+tr[tr[p].r].val;
    }
    int modify(int rt,int l,int r,int x){
        if(!rt)rt=++tot;
        if(l==r){
            tr[rt].val++;
            return rt;
        }
        int mid=(l+r)/2;
        if(x<=mid)tr[rt].l=modify(tr[rt].l,l,mid,x);
        else tr[rt].r=modify(tr[rt].r,mid+1,r,x);
        pushup(rt);
        return rt;
    }
    int merge(int x,int y,int l,int r){
        if(!x||!y){
            return x+y;
        }
        if(l==r){
            tr[x].val+=tr[y].val;
            return x;
        }
        int mid=(l+r)/2;
        tr[x].l=merge(tr[x].l,tr[y].l,l,mid);
        tr[x].r=merge(tr[x].r,tr[y].r,mid+1,r);
        pushup(x);
        return x;
    }
    void split(int x,int &y,int k){//x留下最小的k个
        if(!x)return;
        y=++tot;
        int v=tr[tr[x].l].val;
        if(k>v){
            split(tr[x].r,tr[y].r,k-v);
        }else{
            swap(tr[x].r,tr[y].r);
        }
        if(k<v){
            split(tr[x].l,tr[y].l,k);
        }
        pushup(x);
        pushup(y);
        // tr[y].val=tr[x].val-k;
        // tr[x].val=k;
    }
    void split2(int x,int &y,int k){//x留下最大的k个
        if(!x)return;
        y=++tot;
        int v=tr[tr[x].r].val;
        if(k>v){
            split2(tr[x].l,tr[y].l,k-v);
        }else{
            swap(tr[x].l,tr[y].l);
        }
        if(k<v){
            split2(tr[x].r,tr[y].r,k);
        }
        pushup(x);
        pushup(y);
        // tr[y].val=tr[x].val-k;
        // tr[x].val=k;
    }
    int querykth(int rt,int l,int r,int k){
        if(l==r)return l;
        int mid=(l+r)/2;
        int v=tr[tr[rt].l].val;
        //debug(l,r,v,tr[rt].val);
        if(k<=v){
            return querykth(tr[rt].l,l,mid,k);
        }else{
            return querykth(tr[rt].r,mid+1,r,k-v);
        }
    }
}T;
set<int> s;
int n,m,rt[N],flag[N];//rt[x]代表以x开头这一段线段树的根
void solve(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        rt[i]=T.modify(rt[i],1,n,x);
        s.insert(i);
        flag[i]=0;
    }
    s.insert(0);
    s.insert(n+1);
    for(int i=1;i<=m;i++){
        int op,l,r;
        cin>>op>>l>>r;

        set<int>::iterator posl,posr;
        auto tmp1=--s.upper_bound(l);
        if(*tmp1==l){
            posl=tmp1;
        }else{
            posl=s.insert(l).first;
            //debug(*posl,nxtl);
            //debug(T.tr[rt[*tmp1]].val);
            if(flag[*tmp1]==0){
                T.split(rt[*tmp1],rt[l],l-(*tmp1));
            }else{
                T.split2(rt[*tmp1],rt[l],l-(*tmp1));
            }
            flag[l]=flag[*tmp1];
            //debug(*tmp1,l-(*tmp1),T.tr[rt[l]].val,T.tr[T.tr[rt[l]].l].val);
        }

        auto tmp2=s.lower_bound(r+1);//r下一块的块头
        //debug(*tmp2-1);//包含r的块的末尾
        if(*tmp2-1==r){
            posr=tmp2;
        }else{
            posr=s.insert(r+1).first;
            auto prer=prev(posr);
            //debug(*prer);//包含r的块的开头
            if(flag[*prer]==0){
                T.split(rt[*prer],rt[r+1],r-*prer+1);
            }else{
                T.split2(rt[*prer],rt[r+1],r-*prer+1);
            }
            flag[r+1]=flag[*prer];
            //debug(*posr,r-*prer+1,T.tr[rt[l]].val);
        }
        
        for(auto i=next(posl);i!=posr;i++){
            //debug(*i);
            rt[l]=T.merge(rt[l],rt[*i],1,n);
        }
        //debug(*posl,*posr,T.tr[rt[l]].val);
        s.erase(posl,posr);
        s.insert(l);
        flag[l]=op;
    }
    int q;
    cin>>q;
    int pos=*(--s.upper_bound(q));
    //debug(pos,flag[pos]);
    //debug(rt[pos]);
    int nxt=*next(s.lower_bound(q))-1;
    cout<<(!flag[pos]?T.querykth(rt[pos],1,n,q-pos+1):T.querykth(rt[pos],1,n,nxt-q+1));
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t,multitest=0;
    if(multitest)cin>>t;
    else t=1;
    while(t--){
        solve();
    }
    return 0;
}
2024/8/28 17:38
加载中...