替罪羊树

y2823774827y

2019-11-24 17:31:03

Personal

P3369写了道模板题 - 不需要记录父亲节点 - 替罪羊树查询排名较方便,多利用这个去进行其他操作 - 一次插入时仅重构一个子树 在压行的道路上一去不复返 ```cpp #include<bits/stdc++.h> typedef int LL; typedef double dl; #define opt operator const LL maxn=1e5+9; const dl eps=1e-12,pi=acos(-1.0),wyn=0.7; LL Read(){ LL x(0),f(1); char c=getchar(); while(c<'0' || c>'9'){ if(c=='-') f=-1; c=getchar(); } while(c>='0' && c<='9'){ x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }return x*f; } struct node{ LL v,son[2],size,tag,cnt; }a[maxn]; LL m,top,nod,root,tmp; LL cal[maxn]; void Build(LL &nw,LL l,LL r){ if(l>r) return; LL mid(l+r>>1); nw=cal[mid]; a[nw].size=r-l+1; Build(a[nw].son[0],l,mid-1); Build(a[nw].son[1],mid+1,r); a[nw].cnt=a[a[nw].son[0]].cnt+a[a[nw].son[1]].cnt+a[nw].tag; } void Recyle(LL &nw){ if(!nw) return; Recyle(a[nw].son[0]); cal[++top]=nw; Recyle(a[nw].son[1]); nw=0; } void Rebuild(LL &nw){ top=0; Recyle(nw); Build(nw,1,top); } bool Check(LL &nw){ LL zz(a[nw].size*wyn); if(a[a[nw].son[0]].size>=zz || a[a[nw].son[1]].size>=zz) return true; return false; } void Insert(LL &nw,LL x){ if(!nw){ nw=++nod; a[nw].size=a[nw].cnt=1; a[nw].v=x; a[nw].tag=1; return; } a[nw].size++; a[nw].cnt++; if(a[nw].v>=x) Insert(a[nw].son[0],x); else Insert(a[nw].son[1],x); if(Check(nw)) tmp=nw; } void Rept(LL &nw,LL x){ if(nw==tmp){ Rebuild(nw); return; } if(a[nw].v>=x) Rept(a[nw].son[0],x); else Rept(a[nw].son[1],x); } void Erase(LL &nw,LL x){ --a[nw].cnt; if(a[nw].tag && a[a[nw].son[0]].cnt==x-1){ a[nw].tag=0; return; } if(a[a[nw].son[0]].cnt>=x) Erase(a[nw].son[0],x); else Erase(a[nw].son[1],x-a[a[nw].son[0]].cnt-a[nw].tag); } LL Q_rk(LL nw,LL x){ if(!nw) return 0; if(a[nw].v>=x) return Q_rk(a[nw].son[0],x); return a[a[nw].son[0]].cnt+a[nw].tag+Q_rk(a[nw].son[1],x); } LL Q_v(LL nw,LL x){ if(a[a[nw].son[0]].cnt+a[nw].tag==x && a[nw].tag) return a[nw].v; if(a[a[nw].son[0]].cnt>=x) return Q_v(a[nw].son[0],x); else return Q_v(a[nw].son[1],x-a[a[nw].son[0]].cnt-a[nw].tag); } LL Q_pre(LL nw,LL x){ return Q_v(root,Q_rk(root,x)); } LL Q_nxt(LL nw,LL x){ return Q_v(root,Q_rk(root,x+1)+1); } int main(){ m=Read(); LL ret(0); while(m--){ LL op(Read()),x(Read()); switch (op){ case 1:tmp=0; Insert(root,x); if(tmp) Rept(root,x); break; case 2:Erase(root,Q_rk(root,x)+1); break; case 3:printf("%d\n",Q_rk(root,x)+1); break; case 4:printf("%d\n",Q_v(root,x)); break; case 5:printf("%d\n",Q_pre(root,x)); break; case 6:printf("%d\n",Q_nxt(root,x)); break; } } return 0; } ```