郁闷的出纳员
link
约等于平衡树模板题。不知道为什么平衡树似乎总是和我有仇,怎么写怎么错。仅以此篇博客纪念我与平衡树之间的斗争的阶段性胜利。
这道题相当于是要求支持三个操作,插入,查找排名为k的数,删除小于某个值的所有元素。这些都是平衡树的基本操作,第三个只需插入一个那样的节点,把它旋转到根部,如何删除左子树即可。
以上操作似乎SPLAY或者无旋treap要好弄一些,但我还没写过……
#include
#include
#include
//#define zczc
const int N=300010;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int m,n,add,in,root,ans;
char w;
#define lc t[wh].l
#define rc t[wh].r
struct node{
int l,r,data,sum,num,p;
}t[N<<1];
int cnt;
inline int newone(int val){
t[++cnt].data=val;t[cnt].num=t[cnt].sum=1;
t[cnt].p=rand();return cnt;
}
inline void pushup(int wh){
t[wh].sum=t[lc].sum+t[rc].sum+t[wh].num;
}
inline int zig(int wh){
int a=wh,b=lc,c=t[lc].r;
return t[a].l=c,pushup(a),t[b].r=a,pushup(b),b;
}
inline int zag(int wh){
int a=wh,b=rc,c=t[rc].l;
return t[a].r=c,pushup(a),t[b].l=a,pushup(b),b;
}
int insert(int wh,int val){
if(!wh)return newone(val);
if(t[wh].data==val)return t[wh].num++,t[wh].sum++,wh;
if(val1)return t[wh].num--,t[wh].sum--,wh;
if(!lc&&!rc)return 0;
wh=t[lc].p>t[rc].p?zig(wh):zag(wh);
}
if(val'Z')w=getchar();read(in);
if(w=='I'){
if(in