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;
}