/************************** 自己写的代码 **************************/ # include <bits/stdc++.h>
typedef long long int LL;
const int N = 200000+7; const int INF = (~(1<<31)); inline int read(){ int x=0,f=1;char ch=getchar(); for(;ch<'0'||'9'<ch;ch=getchar()) if(ch=='-')f=-1; for(;'0'<=ch&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0'; return x*f; }
/*******************************************************/
/*************SPLAY-tree************/
int n,m;
int ch[N][2]; //ch[][0] lson ch[][1] rson int f[N]; //father int sz[N]; //size int val[N]; //value of node_i int cnt[N]; // counts of the node_i int root; //root of splay-tree int tot; //tot,total,is the number of node of tree
void pushup(int x){ if(x)sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x]; }
void rotate(int x,int k){ // k = 0 左旋, k = 1 右旋 int y=f[x];int z=f[y]; ch[y][!k]=ch[x][k];if(ch[x][k])f[ch[x][k]]=y; f[x]=z;if(z)ch[z][ch[z][1]==y]=x; f[y]=x;ch[x][k]=y; pushup(y),pushup(x); }
void splay(int x,int goal){ for(int y=f[x];f[x]!=goal;y=f[x]) rotate(x,(ch[y][0]==x)); if(goal==0) root=x; }
void newnode(int rt,int v,int fa){ // printf("newnode : rt = %d\n",rt); f[rt]=fa;val[rt]=v,sz[rt]=cnt[rt]=1; ch[rt][0]=ch[rt][1]=0; }
void delnode(int &rt){ //其实是为内存回收做准备的 回头再完善 f[rt]=val[rt]=sz[rt]=cnt[rt]=0; ch[rt][0]=ch[rt][1]=rt=0; }
/***************************以下是DEBUG***************************/
void Traversal(int rt){ if(!rt) return; Traversal(ch[rt][0]); printf("%d f[]=%d sz[]=%d lson=%d rson=%d val[]=%d\n",rt,f[rt],sz[rt],ch[rt][0],ch[rt][1],val[rt]); Traversal(ch[rt][1]); } void debug(){ printf("ROOT = %d <---\n",root); Traversal(root); }
/**************************以下是前置操作**************************/
//以x为根的子树 的极值点 0 极小 1 极大 int extreme(int x,int k){ while(ch[x][k])x=ch[x][k];splay(x,0); return x; } //以x为根的子树 第k个数的位置 int kth(int x,int k){ if(sz[ch[x][0]]+1<=k&&k<=sz[ch[x][0]]+cnt[x]) return x; else if(sz[ch[x][0]]>=k) return kth(ch[x][0],k); else return kth(ch[x][1],k-sz[ch[x][0]]-cnt[x]); } int search(int rt,int x){ if(ch[rt][0]&&val[rt]>x) return search(ch[rt][0],x); else if(ch[rt][1]&&val[rt]<x)return search(ch[rt][1],x); else return rt; } /***************************以下是正经操作*************************/ //前驱 int prec(int x){ int k=search(root,x); splay(k,0);//debug(); if(val[k]<x) return k; return extreme(ch[k][0],1); } //后继 int sufc(int x){ int k=search(root,x); splay(k,0);//debug(); if(val[k]>x) return k; return extreme(ch[k][1],0); } int rk(int x){ int k=search(root,x); splay(k,0); return sz[ch[root][0]]+1; } //按照二叉排序树性质插入x void _insert(int x){ int y=search(root,x),k=-1; if(val[y]==x){ cnt[y]++; sz[y]++; for(int yy=y;yy;yy=f[yy]) pushup(yy); } else { int p=prec(x),s=sufc(x); splay(p,0);splay(s,p); newnode(++tot,x,ch[root][1]); ch[ch[root][1]][0]=tot; for(int z=ch[root][1];z;z=f[z])pushup(z); } if(k==-1) splay(y,0);else splay(tot,0); }
void _delete(int x){ int y=search(root,x); if(val[y]!=x) return; if(cnt[y]>1){ cnt[y]--; sz[y]--; for(int yy=y;yy;yy=f[yy]) pushup(yy); } else if(ch[y][0]==0||ch[y][1]==0){ int z=f[y]; ch[z][ch[z][1]==y]=ch[y][ch[y][0]==0]; f[ch[y][ch[y][0]==0]]=z;delnode(y); for(int yy=z;yy;yy=f[yy]) pushup(yy); } else { int p=prec(x),s=sufc(x); splay(p,0);splay(s,p); ch[ch[root][1]][0]=0; delnode(ch[ch[root][1]][0]); for(int yy=s;yy;yy=f[yy]) pushup(yy); } }
/*****************************************************/
int main(){ scanf("%d",&n); tot=0,root=1; newnode(++tot,-INF,0),newnode(++tot,INF,root); ch[root][1]=tot; for(int op,x;n--;){ op=read(),x=read(); if(op==1) _insert(x); else if(op==2) _delete(x); else if(op==3) printf("%d\n",rk(x)-1); else if(op==4) printf("%d\n",val[kth(root,x+1)]); else if(op==5) printf("%d\n",val[prec(x)]); else printf("%d\n",val[sufc(x)]); } return 0; }
/************************** 当年套的模板代码 **************************/ # include <bits/stdc++.h> using namespace std;
const int N = 100000+7;
int root,tot; int father[N],data[N],cnt[N],value[N]; int son[N][3];
inline void Rotate(int x,int w){ int y=father[x]; cnt[y]=cnt[y]-cnt[x]+cnt[son[x][w]]; cnt[x]=cnt[x]-cnt[son[x][w]]+cnt[y]; son[y][3-w]=son[x][w]; if(son[x][w]) father[son[x][w]]=y; father[x]=father[y]; if(father[y]){ if(y==son[father[y]][1]) son[father[y]][1]=x; else son[father[y]][2]=x; } father[y]=x; son[x][w]=y; }
inline void splay(int x){ int y; while(father[x]){ y=father[x]; if(!father[y]){ if(x==son[y][1]) Rotate(x,2); else Rotate(x,1); } else{ if(y==son[father[y]][1]){ if(x==son[y][1]) Rotate(y,2),Rotate(x,2); else Rotate(x,1),Rotate(x,2); } else { if(x==son[y][2]) Rotate(y,1),Rotate(x,1); else Rotate(x,2),Rotate(x,1); } } } root = x; return ; }
inline int Search(int x,int w){ while(data[x]!=w){ if(w==data[x]) return x; if(w<data[x]) { if(!son[x][1]) break; x = son[x][1]; } else { if(!son[x][2]) break; x = son[x][2]; } } return x; }
inline void Insert(int w){ int k,kk;bool flag; if(!tot){ tot=1; father[1]=0;cnt[1]=1;data[1]=w;root=1;value[1]=1; return ; } k = Search(root,w); if(data[k]==w){ value[k]++;kk=k; flag = true; } else{ tot++; data[tot]=w; father[tot]=k; cnt[tot]=1; value[tot]=1; if(data[k]>w) son[k][1]=tot; else son[k][2]=tot; flag = false; } while(k){ cnt[k]++;k=father[k]; } if(flag) splay(kk);else splay(tot); }
inline int Extreme(int x,int w){ const int lala[3]={0,2147483647,-2147483647}; int k=Search(x,lala[w]),tmp; tmp = data[k]; splay(k); return tmp; }
inline void del(int x){ int k=Search(root,x),y; splay(k); if(data[k]==x){ if(value[k]>1){ value[k]--; cnt[k]--; } else if(!son[k][1]){ y=son[k][2]; son[k][2]=0; cnt[k]=0; data[k]=0; value[k]=0; root = y; father[root]=0; } else { father[son[k][1]]=0; y=Extreme(son[k][1],1); son[root][2]=son[k][2]; cnt[root]=cnt[root]+cnt[son[k][2]]; if(son[root][2])father[son[root][2]]=root; data[k]=0;son[k][1];son[k][2]=0; value[k]=0; } } }
inline int pred(int x){ int k = Search(root,x); splay(k); if(data[k]<x) return data[k]; return Extreme(son[k][1],1); }
inline int succ(int x){ int k = Search(root,x); splay(k); if(data[k]>x) return data[k]; return Extreme(son[k][2],2); }
inline int kth(int x,int w){ int i=root,tmp; while(!((x>=cnt[son[i][w]]+1)&&(x<=cnt[son[i][w]]+value[i]))&&i){ if(x>cnt[son[i][w]]+value[i]){ x = x - cnt[son[i][w]]-value[i]; i = son[i][3-w]; } else i = son[i][w]; } tmp = i;splay(i); return tmp; }
inline int findnum(int x){ int k = Search(root,x);splay(k); root = k; return cnt[son[k][1]]+1; }
int main(){ int n,op,x; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&op,&x); if(1==op) Insert(x); else if(2==op) del(x); else if(3==op) printf("%d\n",findnum(x)); else if(4==op) printf("%d\n",data[kth(x,1)]); else if(5==op) printf("%d\n",pred(x)); else if(6==op) printf("%d\n",succ(x)); } return 0; }
|