是我写假了还是 splay 被卡了?

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

```cpp #include<cstdio> using namespace std; int re() { int s=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0') { if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') s=s*10+ch-48,ch=getchar(); return s*f; } void wr(int s) { if(s<0)putchar('-'),s=-s; if(s>9)wr(s/10); putchar(s%10+48); } const int inf=2e6+7; int n,m,last,ans,a[inf]; struct splay{ int fa,hz[2]; int siz,cnt,val; }T[inf],q0; int rot,cnt; void clear(int i){T[i]=q0;} void pushup(int i){T[i].siz=T[T[i].hz[0]].siz+T[T[i].hz[1]].siz+T[i].cnt;} bool pd(int i){return i==T[T[i].fa].hz[1];} void rotate(int i) { int fa=T[i].fa,gf=T[fa].fa; int pdi=pd(i),pdf=pd(fa); T[i].fa=gf;if(gf)T[gf].hz[pdf]=i; if(T[i].hz[pdi^1])T[T[i].hz[pdi^1]].fa=fa; T[fa].hz[pdi]=T[i].hz[pdi^1]; T[fa].fa=i,T[i].hz[pdi^1]=fa; pushup(fa),pushup(i); } void splay(int i,int to) { to=T[to].fa; for(int fa=T[i].fa;fa!=to;rotate(i),fa=T[i].fa) if(T[fa].fa^to)rotate((pd(i)^pd(fa))?i:fa); if(!to)rot=i; } int new_(int k,int fa) { T[++cnt].val=k,T[cnt].fa=fa; T[cnt].siz=T[cnt].cnt=1; return cnt; } void insert(int k) { if(!rot){rot=new_(k,0);return;} int now=rot,fa=0; while(now) { if(k==T[now].val) { T[now].cnt++,T[now].siz++; splay(now,rot);return; } fa=now; if(k<T[now].val)now=T[now].hz[0]; else now=T[now].hz[1]; } now=new_(k,fa); T[fa].hz[k>T[fa].val]=now; splay(now,rot); } int ask_rnk(int k) { int now=rot,ans=0; while(now) { if(T[now].val==k) { int ret=T[T[now].hz[0]].siz; splay(now,rot); return ans+ret+1; } if(k<T[now].val)now=T[now].hz[0]; else ans+=T[T[now].hz[0]].siz+T[now].cnt,now=T[now].hz[1]; } return ans+1; } int ask_kth(int k) { int now=rot; while(1) { if(T[T[now].hz[0]].siz+1<=k&&k<=T[T[now].hz[0]].siz+T[now].cnt) {splay(now,rot);return T[now].val;} if(k<=T[T[now].hz[0]].siz)now=T[now].hz[0]; else k-=T[T[now].hz[0]].siz+T[now].cnt,now=T[now].hz[1]; } } int pre() { int now=T[rot].hz[0]; if(now)while(T[now].hz[1]) now=T[now].hz[1]; return now; } int nex() { int now=T[rot].hz[1]; if(now)while(T[now].hz[0]) now=T[now].hz[0]; return now; } void remove(int k) { ask_rnk(k);int now=rot; if(T[now].cnt>1){T[now].cnt--,T[now].siz--;return;} if(T[now].hz[0]+T[now].hz[1]==0){clear(now),rot=0;return;} if(T[now].hz[0]==0) { rot=T[now].hz[1];T[rot].fa=0; pushup(rot);return; } if(T[now].hz[1]==0) { rot=T[now].hz[0];T[rot].fa=0; pushup(rot);return; } int ls=pre(); splay(ls,rot); T[rot].hz[1]=T[now].hz[1]; T[T[now].hz[1]].fa=rot; clear(now);pushup(rot); } int ask_pre(int k) { insert(k);int ret=T[pre()].val; remove(k);return ret; } int ask_nex(int k) { insert(k);int ret=T[nex()].val; remove(k);return ret; } int main() { n=re();m=re(); for(int i=1;i<=n;i++) a[i]=re(),insert(a[i]); while(m--) { int op=re(),k=re()^last; if(op==1)insert(k); if(op==2)remove(k); if(op==3)last=ask_rnk(k),ans^=last; if(op==4)last=ask_kth(k),ans^=last; if(op==5)last=ask_pre(k),ans^=last; if(op==6)last=ask_nex(k),ans^=last; } wr(ans); return 0; } ```
by Split @ 2022-09-19 13:59:33


rnk 和 kth 没 splay。
by w23c3c3 @ 2022-09-19 14:45:14


@[w23c3c3](/user/109942) 我在 return 之前 splay 了啊
by Split @ 2022-09-19 14:47:02


o。 但是你在 askrank 的时候假如一直到最后了那你不是就没 splay 了嘛。
by w23c3c3 @ 2022-09-19 14:47:56


@[w23c3c3](/user/109942) 没看懂qwq
by Split @ 2022-09-19 14:49:03


就是你这个 askrank 不是有个 while 嘛,然后跑满了这个 while 你就返回 ans+1 了,那他就可以一直跑满这个 while 吧。
by w23c3c3 @ 2022-09-19 14:54:54


@[w23c3c3](/user/109942) 可是我这样也是 T qwq ```cpp const int inf=2e6+7; int n,m,last,ans,a[inf]; struct splay{ int fa,hz[2]; int siz,cnt,val; }T[inf],q0; int rot,cnt; void clear(int i){T[i]=q0;} void pushup(int i){T[i].siz=T[T[i].hz[0]].siz+T[T[i].hz[1]].siz+T[i].cnt;} bool pd(int i){return i==T[T[i].fa].hz[1];} void rotate(int i) { int fa=T[i].fa,gf=T[fa].fa; int pdi=pd(i),pdf=pd(fa); T[i].fa=gf;if(gf)T[gf].hz[pdf]=i; if(T[i].hz[pdi^1])T[T[i].hz[pdi^1]].fa=fa; T[fa].hz[pdi]=T[i].hz[pdi^1]; T[fa].fa=i,T[i].hz[pdi^1]=fa; pushup(fa),pushup(i); } void splay(int i,int to) { to=T[to].fa; for(int fa=T[i].fa;fa!=to;rotate(i),fa=T[i].fa) if(T[fa].fa^to)rotate((pd(i)^pd(fa))?i:fa); if(!to)rot=i; } int new_(int k,int fa) { T[++cnt].val=k,T[cnt].fa=fa; T[cnt].siz=T[cnt].cnt=1; return cnt; } void insert(int k) { if(!rot){rot=new_(k,0);return;} int now=rot,fa=0; while(now) { if(k==T[now].val) { T[now].cnt++,T[now].siz++; splay(now,rot);return; } fa=now; if(k<T[now].val)now=T[now].hz[0]; else now=T[now].hz[1]; } now=new_(k,fa); T[fa].hz[k>T[fa].val]=now; splay(now,rot); } int rnk(int k) { int now=rot,ans=0; while(1) { if(T[now].val==k) { int ret=T[T[now].hz[0]].siz; splay(now,rot); return ans+ret+1; } if(k<T[now].val)now=T[now].hz[0]; else ans+=T[T[now].hz[0]].siz+T[now].cnt,now=T[now].hz[1]; } } int ask_kth(int k) { int now=rot; while(1) { if(T[T[now].hz[0]].siz+1<=k&&k<=T[T[now].hz[0]].siz+T[now].cnt) {splay(now,rot);return T[now].val;} if(k<=T[T[now].hz[0]].siz)now=T[now].hz[0]; else k-=T[T[now].hz[0]].siz+T[now].cnt,now=T[now].hz[1]; } } int pre() { int now=T[rot].hz[0]; if(now)while(T[now].hz[1]) now=T[now].hz[1]; return now; } int nex() { int now=T[rot].hz[1]; if(now)while(T[now].hz[0]) now=T[now].hz[0]; return now; } void remove(int k) { rnk(k);int now=rot; if(T[now].cnt>1){T[now].cnt--,T[now].siz--;return;} if(T[now].hz[0]+T[now].hz[1]==0){clear(now),rot=0;return;} if(T[now].hz[0]==0) { rot=T[now].hz[1];T[rot].fa=0; pushup(rot);return; } if(T[now].hz[1]==0) { rot=T[now].hz[0];T[rot].fa=0; pushup(rot);return; } int ls=pre(); splay(ls,rot); T[rot].hz[1]=T[now].hz[1]; T[T[now].hz[1]].fa=rot; clear(now);pushup(rot); } int ask_rnk(int k) { insert(k);int ret=rnk(k); remove(k);return ret; } int ask_pre(int k) { insert(k);int ret=T[pre()].val; remove(k);return ret; } int ask_nex(int k) { insert(k);int ret=T[nex()].val; remove(k);return ret; } int main() { n=re();m=re(); for(int i=1;i<=n;i++) a[i]=re(),insert(a[i]); while(m--) { int op=re(),k=re()^last; if(op==1)insert(k); if(op==2)remove(k); if(op==3)last=ask_rnk(k),ans^=last; if(op==4)last=ask_kth(k),ans^=last; if(op==5)last=ask_pre(k),ans^=last; if(op==6)last=ask_nex(k),ans^=last; } wr(ans); return 0; } ```
by Split @ 2022-09-19 16:34:19


我好像还是没有理解您的意思,所以应该怎么 Splay ?qwq
by Split @ 2022-09-19 16:35:31


找到原因了,pre 和 nex 没有 splay……,留此贴以警示后人
by Split @ 2022-09-19 17:00:20


@[Split](/user/458627) 感谢大佬%%%%%
by C_liar @ 2022-12-03 10:18:14


|