萌新刚学平衡树求助

P6136 【模板】普通平衡树(数据加强版)

Polariserist @ 2020-11-28 09:03:11

RT,替罪羊树MLE,求大佬帮忙 code</>

#include<bits/stdc++.h>
using namespace std;
const int maxn=100100;
const double alpha=0.7;
int tree[maxn],tl[maxn],tr[maxn],size[maxn],tid[maxn];
vector<int>fp,fn,fv;
int cnt=1;
int flatten(int pos){
    if(!(tree[tl[pos]]==0&&tl[tl[pos]]==0&&tr[tl[pos]]==0)){
        flatten(tl[pos]);
    }
    int id=fp.size();
    if(tree[pos]){
        fp.push_back(pos);
        fn.push_back(tid[pos]);
        fv.push_back(tree[pos]);
    }
    if(!(tree[tr[pos]]==0&&tl[tr[pos]]==0&&tr[tr[pos]]==0)){
        flatten(tr[pos]);
    }
    return id;
}
void rebuild(int pos,int l=0,int r=fp.size()-1){
    int mid=(l+r)/2,szl=0,szr=0;
    if(l<mid){
        tl[pos]=fp[(l+mid-1)/2];
        rebuild(tl[pos],l,mid-1);
        szl=size[tl[pos]];
    }
    else{
        tl[pos]=0;
    }
    if(r>mid){
        tr[pos]=fp[(mid+1+r)/2];
        rebuild(tr[pos],mid+1,r);
        szr=size[tr[pos]];
    }
    else{
        tr[pos]=0;
    }
    tree[pos]=fv[mid];
    tid[pos]=fn[mid];
    size[pos]=szl+szr+tid[pos];
}
void try_restructure(int pos){
    double k=max(size[tl[pos]],size[tr[pos]])/(double)size[pos];
    if(k>alpha){
        fp.clear();
        fv.clear();
        fn.clear();
        int id=flatten(pos);
        swap(fp[id],fp[(fp.size()-1)/2]);
        rebuild(pos);
    }
}
void insert(int v,int pos=1){
    if((tree[pos]==0&&tl[pos]==0&&tr[pos]==0)){
        tree[pos]=v;
        tid[pos]=1;
    }
    else if(v<tree[pos]){
        if((tree[tl[pos]]==0&&tl[tl[pos]]==0&&tr[tl[pos]]==0)){
            tl[pos]=++cnt;
        }
        insert(v,tl[pos]);
    }
    else if(v>tree[pos]){
        if((tree[tr[pos]]==0&&tl[tr[pos]]==0&&tr[tr[pos]]==0)){
            tr[pos]=++cnt;
        }
        insert(v,tr[pos]);
    }
    else{
        tid[pos]++;
    }
    size[pos]++;
    try_restructure(pos);
}
void remove(int v,int pos=1){
    size[pos]--;
    if(v<tree[pos]){
        remove(v,tl[pos]);
    }
    else if(v>tree[pos]){
        remove(v,tr[pos]);
    }
    else{
        tid[pos]--;
    }
    try_restructure(pos);
}
int countl(int v,int pos=1){
    if(v<tree[pos]){
        if((tree[tl[pos]]==0&&tl[tl[pos]]==0&&tr[tl[pos]]==0)){
            return 0;
        }
        return countl(v,tl[pos]);
    }
    else if(v>tree[pos]){
        if((tid[tr[pos]]==0&&tl[tr[pos]]==0&&tr[tr[pos]]==0)){
            return size[tl[pos]]+tid[pos];
        }
        return size[tl[pos]]+tid[pos]+countl(v,tr[pos]);
    }
    else{
        return size[tl[pos]];
    }
}
int countr(int v,int pos=1){
    if(v>tree[pos]){
        if((tid[tr[pos]]==0&&tl[tr[pos]]==0&&tr[tr[pos]]==0)){
            return 0;
        }
        return countr(v,tr[pos]);
    }
    else if(v<tree[pos]){
        if((tree[tl[pos]]==0&&tl[tl[pos]]==0&&tr[tl[pos]]==0)){
            return size[tr[pos]]+tid[pos];
        }
        return size[tr[pos]]+tid[pos]+countr(v,tl[pos]);
    }
    else{
        return size[tr[pos]];
    }
}
int ranks(int v){
    return countl(v)+1;
}
int kth(int k,int pos=1){
    if(size[tl[pos]]+1>k){
        return kth(k,tl[pos]);
    }
    else if(size[tl[pos]]+tid[pos]<k){
        return kth(k-size[tl[pos]]-tid[pos],tr[pos]);
    }
    else{
        return tree[pos];
    }
}
int pre(int v){
    int r=countl(v);
    return kth(r);
}
int suc(int v){
    int r=size[1]-countr(v)+1;
    return kth(r);
}
int main(){
    int n,m,last=0,ans=0; 
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        insert(x);
    }
    for(int i=1;i<=m;i++){
        int opt;
        cin>>opt;
        if(opt==1){
            int x;
            cin>>x;
            insert(x);
        }
        if(opt==2){
            int x;
            cin>>x;
            remove(x);
        }
        if(opt==3){
            int x;
            cin>>x;
            x^=last;
            int res=ranks(x);
            last=res;
            ans^=res;
        }
        if(opt==4){
            int x;
            cin>>x;
            x^=last;
            int res=kth(x);
            last=res;
            ans^=res;
        }
        if(opt==5){
            int x;
            cin>>x;
            x^=last;
            int res=pre(x);
            last=res;
            ans^=res;
        }
        if(opt==6){
            int x;
            cin>>x;
            x^=last;
            int res=suc(x);
            last=res;
            ans^=res;
        }
    }
    cout<<ans;
}

|