MnZn求助平衡树模板

P3369 【模板】普通平衡树

```cpp #include<bits/stdc++.h> using namespace std; struct Tree{ int fa,l,r; int s,size; int color; }tree[120000]; int pdpd[100000]; int top=0; void print(){ cout<<"/---------------------------------------------------------------------/"<<endl; printf(" i: S size color fa l r \n"); for(int i=0;i<=top;i++){ if(!pdpd[i])printf("\n%5d %5d %5d %5d %5d %5d %5d\n",i,tree[i].s,tree[i].size,tree[i].color,tree[i].fa,tree[i].l,tree[i].r); } cout<<"//===================================================================//"<<endl; } void zig(int zz){ int x=tree[zz].l,y=tree[zz].fa; tree[tree[x].r].fa=zz; tree[x].fa=y; tree[zz].fa=x; (tree[y].s>tree[zz].s)? tree[y].l=x:tree[y].r=x; tree[zz].l=tree[x].r; tree[x].r=zz; int js=tree[x].size; tree[x].size=tree[zz].size; tree[zz].size=tree[zz].size-js+tree[tree[zz].l].size; } void zag(int zz){ int x=tree[zz].r,y=tree[zz].fa; tree[tree[x].l].fa=zz; tree[x].fa=y; tree[zz].fa=x; (tree[y].s>tree[zz].s)? tree[y].l=x:tree[y].r=x; tree[zz].r=tree[x].l; tree[x].l=zz; int js=tree[x].size; tree[x].size=tree[zz].size; tree[zz].size=tree[zz].size-js+tree[tree[zz].r].size; } void addpoint(int s,int fa){ top++; tree[top].s=s;tree[top].fa=fa;tree[top].l=0;tree[top].r=0; tree[top].size=0;tree[top].color=1; tree[fa].s>s? tree[fa].l=top:tree[fa].r=top; } int findadd(int x,int zz){ if(zz==0){if(tree[0].l)return findadd(x,tree[0].l);else if(tree[0].r)return findadd(x,tree[0].r);else return 0;} if(tree[zz].s==x)return zz; int zzz=zz; if(tree[zz].s>x)zz=tree[zz].l; else zz=tree[zz].r; if(!zz)return zzz; else return findadd(x,zz); } void addgs(int zz,int x){ if(!zz)return ; tree[zz].size+=x; zz=tree[zz].fa; addgs(zz,x); } void check(int x){ // cout<<"check!!! "<<x<<endl; int fa=tree[x].fa; if(fa==0){tree[x].color=0;return ;} if(tree[fa].color!=tree[x].color)return ; int gr=tree[fa].fa; if(gr==0){tree[fa].color=0;return ;} int fx,fx2; int un=(tree[gr].l^fa)? tree[gr].l:tree[gr].r; if(tree[un].color==1){ tree[un].color=0; tree[fa].color=0; tree[gr].color=1; check(gr); } else{ fx=(tree[gr].l^fa)? 2:1; fx2=(tree[fa].l^x)? 2:1; if(fx!=fx2){ if(fx2==1)zig(fa); else zag(fa); swap(x,fa); } tree[gr].color=1; tree[fa].color=0; if(fx==1)zig(gr); else zag(gr); } } void add(int x){ int zz=findadd(x,0); if(tree[zz].s==x){ addgs(zz,1);return ; } addpoint(x,zz); addgs(top,1); check(top); } int find1(int x,int zz){ if(zz==0){if(tree[zz].l)return find1(x,tree[zz].l);else if(tree[zz].r)return find1(x,tree[zz].r);else return 0;} if(tree[zz].s>=x){if(tree[zz].l)return find1(x,tree[zz].l);else return 0;} else {if(tree[zz].r)return tree[zz].size-tree[tree[zz].r].size+find1(x,tree[zz].r);else return tree[zz].size;} } int find2(int x,int zz){ if(x<1)return 0; if(zz==0){if(tree[zz].l)return find2(x,tree[zz].l);else if(tree[zz].r)return find2(x,tree[zz].r);else return 0;} int l=tree[zz].l,r=tree[zz].r; if(l&&x<=tree[l].size)return find2(x,l); if(r&&x>tree[zz].size-tree[r].size)return find2(x-tree[zz].size+tree[r].size,r); return zz; } void Delete(int zz,bool pd){ if(zz==0)return ; // cout<<"Delete: "<<zz<<" "<<pd<<endl; int bro=pd? tree[zz].l:tree[zz].r; int gl=tree[bro].l,gr=tree[bro].r; int my=pd? tree[zz].r:tree[zz].l; if(tree[bro].color==1){ tree[zz].color=1; tree[bro].color=0; pd? zig(zz):zag(zz); // cout<<"brother_color:RED"<<endl; Delete(zz,pd); } else{ if(!pd){//cout<<"L"<<endl; //cout<<"brother_color:BLACK"<<endl; int l=tree[bro].l,r=tree[bro].r; if(r&&tree[r].color==1){ tree[r].color=0; tree[bro].color=tree[zz].color; tree[zz].color=0; zag(zz); // cout<<"end"<<endl; return ; } else if(l&&tree[l].color==1){ tree[l].color=0; tree[bro].color=1; zig(bro); // cout<<"to end"<<endl; Delete(zz,pd); } else{ tree[bro].color=1; pd=(tree[tree[zz].fa].l^zz); if(tree[zz].color==0){//cout<<"We didn't solution , maybe parents can solute it!"<<endl; Delete(tree[zz].fa,pd);} else{ tree[zz].color=0; // cout<<"end"<<endl; return ; } } } else{//cout<<"R"<<endl; //cout<<"brother_color:BLACK"<<endl; int l=tree[bro].l,r=tree[bro].r; if(l&&tree[l].color==1){ tree[l].color=0; tree[bro].color=tree[zz].color; tree[zz].color=0; zig(zz); // cout<<"end"<<endl; return ; } else if(r&&tree[r].color==1){ tree[r].color=0; tree[bro].color=1; zag(bro); // cout<<"to end"<<endl; Delete(zz,pd); } else{ tree[bro].color=1; pd=(tree[tree[zz].fa].l^zz); if(tree[zz].color==0){//cout<<"We didn't solution , maybe parents can solute it!"<<endl; Delete(tree[zz].fa,pd);} else{ tree[zz].color=0; // cout<<"end"<<endl; return ; } } } } } void dalete(int x){ int zz=findadd(x,0); if(tree[zz].s!=x)return ; // cout<<"find! "<<zz<<endl; if(tree[zz].size>tree[tree[zz].l].size+tree[tree[zz].r].size+1){addgs(zz,-1);return ;} int ztop=find2(find1(x,zz),zz); int fa=tree[ztop].fa;bool js; if(ztop&&ztop!=zz){ // cout<<"QaQ "<<ztop<<endl; tree[zz].s=tree[ztop].s; tree[zz].size=tree[ztop].size-tree[tree[ztop].l].size-tree[tree[ztop].r].size+tree[tree[zz].l].size+tree[tree[zz].r].size; js=(tree[fa].l^ztop); (tree[fa].l^ztop)? tree[fa].r=tree[ztop].l:tree[fa].l=tree[ztop].l; if(tree[ztop].l) tree[tree[ztop].l].fa=fa; } else{ // cout<<"QwQ"<<endl; ztop=zz; fa=tree[ztop].fa; js=(tree[fa].l^ztop); (tree[fa].l^ztop)? tree[fa].r=tree[ztop].r:tree[fa].l=tree[ztop].r; if(tree[ztop].r) tree[tree[ztop].r].fa=fa; }int jian=-tree[ztop].size; if(tree[ztop].l)jian+=tree[tree[ztop].l].size; if(tree[ztop].r)jian+=tree[tree[ztop].r].size; addgs(fa,jian); if(zz!=ztop)addgs(zz,-jian-1); // cout<<zz<<" "<<ztop<<" "<<fa<<" *******"<<endl; pdpd[ztop]=1; if(tree[ztop].color==0){ if(js==1&&tree[tree[fa].r].color==1){ tree[tree[fa].r].color=0; } else if(js==0&&tree[tree[fa].l].color==1){ tree[tree[fa].l].color=0; } else Delete(fa,js); } } void csh(){ tree[0].color=0;tree[0].l=0;tree[0].r=0;tree[0].fa=-1; tree[0].s=0;tree[0].size=0; } int main(){ // freopen("1.in","r",stdin); // freopen("bf.out","w",stdout); int T; cin>>T; int ppdd=0; while(T){ T--; int n,m; scanf("%d%d",&n,&m); if(n==1)add(m); else if(n==2)dalete(m); else if(n==3)printf("%d\n",find1(m,0)+1); else if(n==4)printf("%d\n",tree[find2(m,0)].s); else if(n==5)printf("%d\n",tree[find2(find1(m,0),0)].s); else if(n==6){ int jkl=find1(m,0); int zz=findadd(m,0); jkl++; if(tree[zz].s==m){ jkl+=tree[zz].size-tree[tree[zz].l].size-tree[tree[zz].r].size; } printf("%d\n",tree[find2(jkl,0)].s); }/* if(n!=1&&n!=2){ppdd++; if(ppdd>28&&ppdd<32)print();}*/ //print(); } //print(); } ```
by 天南星魔芋 @ 2021-03-15 18:07:44


~~变量名太诡异不想调~~ 试试把数组开大亿点点
by JJA_ @ 2021-03-15 18:37:36


@[蒟蒻JJA](/user/352464) ~~谢谢,不过貌似没用~~
by 天南星魔芋 @ 2021-03-15 20:03:57


|