bzoj1503
treap改了好长时间,erase写错了。。。
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; const int inf=1<<29; int n,mn,root,delta,tot,leave; int key[100010],cnt[100010],size[100010],p[100010]; int child[100010][2]; void update(int x) { size[x]=size[child[x][0]]+size[child[x][1]]+cnt[x]; } void rotate(int&x,int t) { int y=child[x][t]; child[x][t]=child[y][1-t]; child[y][1-t]=x; update(x); update(y); x=y; } void insert(int&x,int k) { if(x) { if(key[x]==k) { cnt[x]++; update(x); return; } int t=key[x]<k; insert(child[x][t],k); if(p[x]<p[child[x][t]]) rotate(x,t); update(x); } else { tot++; x=tot; p[x]=rand(); key[x]=k; cnt[x]=1; update(x); } } void erase(int&x,int k) { if(key[x]==k) { if(!child[x][0]&&!child[x][1]) { x=0; return; } int t=p[child[x][1]]>p[child[x][0]]; rotate(x,t); erase(child[x][t^1],k); } else erase(child[x][key[x]<k],k); update(x); } void _erase(int x) { if(x==0) return; if(key[x]+delta<mn) { leave+=cnt[x]; if(key[child[x][0]]+delta<mn) { leave+=size[child[x][0]]; child[x][0]=0; update(x); } _erase(child[x][1]); erase(root,key[x]); } _erase(child[x][0]); } int find(int x,int k) { if(k<=size[child[x][1]]) return find(child[x][1],k); k-=size[child[x][1]]+cnt[x]; if(k<=0) return key[x]; return find(child[x][0],k); } int main() { p[0]=-inf; scanf("%d%d",&n,&mn); while(n--) { char s[10]; int k; scanf("%s%d",s,&k); if(s[0]=='I') { if(k>=mn) insert(root,k-delta); } if(s[0]=='A') { delta+=k; } if(s[0]=='S') { delta-=k; _erase(root); } if(s[0]=='F') { if(k>size[root]) printf("-1\n"); else printf("%d\n",find(root,k)+delta); } } printf("%d\n",leave); return 0; }
splay
#include<cstdio> #include<cstring> using namespace std; struct data { int fa,l,r,size,cnt,key; }tree[100010]; int root,n,tot,ans; int abs(int x) { return x>0?x:-x; } void update(int x) { tree[x].size=tree[tree[x].l].size+tree[tree[x].r].size+tree[x].cnt; } void zig(int x) { int y=tree[x].fa; int z=tree[x].r; tree[y].l=z; tree[z].fa=y; tree[x].fa=tree[y].fa; if(y==tree[tree[y].fa].l) tree[tree[y].fa].l=x; else tree[tree[y].fa].r=x; tree[x].r=y; tree[y].fa=x; update(x); update(y); } void zag(int x) { int y=tree[x].fa; int z=tree[x].l; tree[y].r=z; tree[z].fa=y; tree[x].fa=tree[y].fa; if(y==tree[tree[y].fa].l) tree[tree[y].fa].l=x; else tree[tree[y].fa].r=x; tree[x].l=y; tree[y].fa=x; update(x); update(y); } void splay(int x) { if(!root) { root=x; return; } while(tree[x].fa) { int y=tree[x].fa; int z=tree[y].fa; if(y==root) { if(x==tree[root].l) zig(x); else zag(x); update(x); break; } else if(y==tree[z].l&&x==tree[y].l) {zig(y); zig(x);} else if(y==tree[z].r&&x==tree[y].r) {zag(y); zag(x);} else if(y==tree[z].l&&x==tree[y].r) {zag(x); zig(x);} else if(y==tree[z].r&&x==tree[y].l) {zig(x); zag(x);} update(x); } root=x; } void insert(int x,int k) { if(tree[x].key==k) { tree[x].cnt++; update(x); splay(x); } else if(tree[x].key<k) { if(tree[x].r==0) { ++tot; tree[tot].fa=x; if(x) tree[x].r=tot; tree[tot].key=k; tree[tot].cnt=1; update(tot); splay(tot); return; } insert(tree[x].r,k); update(x); } else if(tree[x].key>k) { if(tree[x].l==0) { ++tot; tree[tot].fa=x; if(x) tree[x].l=tot; tree[tot].key=k; tree[tot].cnt=1; update(tot); splay(tot); return; } insert(tree[x].l,k); update(x); } } int search(int x,int k) { if(tree[x].key==k) return x; if(tree[x].key<k) return search(tree[x].r,k); if(tree[x].key>k) return search(tree[x].l,k); } void findnxt(int x,int k,int pd) { if(x==0) return; if(pd==5) { if(tree[x].key<k) { ans=x; findnxt(tree[x].r,k,pd); } else findnxt(tree[x].l,k,pd); } else { if(tree[x].key>k) { ans=x; findnxt(tree[x].l,k,pd); } else findnxt(tree[x].r,k,pd); } } void erase(int x) { findnxt(root,x,5); int pos=search(root,x); splay(pos); if(tree[pos].cnt>1) { tree[pos].cnt--; update(pos); splay(pos); return; } if(ans==0) { root=tree[pos].r; tree[root].fa=0; return; } if(tree[x].r==0) { root=tree[x].l; tree[root].fa=0; return; } // printf("%d %d\n",pos,pro); tree[tree[pos].r].fa=ans; tree[tree[pos].l].fa=0; root=tree[pos].l; tree[ans].r=tree[pos].r; splay(ans); ans=0; } int findrank(int x) { int pos=search(root,x); splay(pos); return tree[tree[pos].l].size+1; } int find(int x,int k) { int y=tree[x].l; int z=tree[x].r; if(k<=tree[z].size) return find(z,k); // printf("%d %d\n",tree[x].cnt,tree[z].size); k-=tree[z].size+tree[x].cnt; if(k<=0) return tree[x].key; return find(y,k); } int main() { scanf("%d",&n); while(n--) { int opt,x; scanf("%d%d",&opt,&x); if(opt==1) { insert(root,x); } if(opt==2) { erase(x); } if(opt==3) { printf("%d\n",findrank(x)); } if(opt==4) { printf("%d\n",find(root,x)); } if(opt==5) { findnxt(root,x,opt); printf("%d\n",tree[ans].key); ans=0; } if(opt==6) { findnxt(root,x,opt); printf("%d\n",tree[ans].key); ans=0; } } return 0; }