普通平衡树,模板的不能再模板的模板题。我调了两个小时。。。
早先看yyb大神的blog学习splay,看的风生水起然而没有发现,大神的坑没有填……没有rank操作和k_th操作。
只能自己摸索,问问大佬。
yzh巨佬拨冗花了五分钟给我解释清楚了k_th和rank求得东西是不去重的(用拙劣的语言表达大神高超的技巧,诸位勿喷)并且给我讲明白了size的各种操作以及妙用后我就再也不会把cnt和size写混了,就回去自己写。
和同桌lyl大佬一起写完,一起T10……然后lyl大佬果断在平衡树中插入了inf和-inf(#define inf 0x7fffffff),A掉了,直降7000毫。
蒟蒻颓了lyl大佬的想法也加了这么个东西,顺手改了一下k_th的求法,W20绝望。
因为和lyl大佬看的同一份模板,我们对了一下各个函数,发现写的一毛一样。绝望+1。
去找调代码专家ooo巨佬对了一遍,完全一样。绝望+999。
最后找到了动动神佬,动动神佬花了三分钟找到了错误:查前驱的时候一个变量名写错了…… /一脸复杂 /生无可恋 /死掉算了
罚自己默写三遍splay模板
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #define read(a) a=init() using namespace std; struct node{ long long fa,ch[2],data,size,cnt; }t[10000003]; long long n,root=0,tot=0,lei,thi; inline long long init() { long long a=0,b=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')b=-1;ch=getchar();} while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+(ch-'0');ch=getchar();} return a*b; } inline void rotate(long long x) { long long y=t[x].fa; long long z=t[y].fa; long long k=t[y].ch[1]==x; t[z].ch[t[z].ch[1]==y]=x; t[x].fa=z; t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].fa=y; t[x].ch[k^1]=y; t[y].fa=x; t[y].size=t[t[y].ch[0]].size+t[t[y].ch[1]].size+t[y].cnt; t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt; } inline void splay(long long x,long long goal) { while(t[x].fa!=goal) { long long y=t[x].fa,z=t[y].fa; if(z!=goal) (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y); rotate(x); } if(!goal)root=x; } inline void insert(long long x) { long long u=root; long long ff=0; while(u&&x!=t[u].data) { ff=u; u=t[u].ch[x>t[u].data]; } if(u) t[u].cnt++; else { u=++tot; if(ff)t[ff].ch[x>t[ff].data]=u; t[u].fa=ff; t[u].ch[0]=t[u].ch[1]=0; t[u].size=1; t[u].data=x; t[u].cnt=1; } splay(u,0); } inline void find(long long x) { long long u=root; if(!u)return ; while(t[u].ch[x>t[u].data]&&x!=t[u].data) u=t[u].ch[x>t[u].data]; splay(u,0); } inline long long nxt(long long x,long long f) { find(x); long long u=root; if(t[u].data>x&&f)return u; if(t[u].data<x&&!f)return u; u=t[u].ch[f]; while(t[u].ch[f^1])u=t[u].ch[f^1]; return u; } inline void delet(long long x) { long long last=nxt(x,0); long long next=nxt(x,1); splay(last,0); splay(next,last); long long del=t[next].ch[0]; if(t[del].cnt>1) { t[del].cnt--; splay(del,0); } else t[next].ch[0]=0; } inline long long rnk(long long x) { find(x); return t[t[root].ch[0]].size; } inline long long k_th(long long x) { long long u=root; if(t[u].size<x)return 0; while(1) { int y=t[u].ch[0]; if(x>t[y].size+t[u].cnt) { x-=t[y].size+t[u].cnt; u=t[u].ch[1]; } else if(t[y].size>=x)u=y; else return t[u].data; } } int main() { read(n); insert(0x7fffffff); insert(-0x7fffffff); for(register long long i=1;i<=n;++i) { read(lei),read(thi); switch(lei) { case 1:{ insert(thi); break; } case 2:{ delet(thi); break; } case 3:{ printf("%lld ",rnk(thi)); break; } case 4:{ printf("%lld ",k_th(thi+1)); break; } case 5:{ printf("%lld ",t[nxt(thi,0)].data); break; } case 6:{ printf("%lld ",t[nxt(thi,1)].data); break; } } } return 0; }