萌新刚学平衡树求助
查看原帖
萌新刚学平衡树求助
171513
Polariserist楼主2020/11/28 09:03

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;
}
2020/11/28 09:03
加载中...