Splay(单点修改+查询)
仅供参考。。。
#include<bits/stdc++.h> using namespace std; char readc(){ static char buf[100000], *l=buf,*r=buf; if (l==r) r=(l=buf)+fread(buf,1,100000,stdin); if (l==r) return EOF;else return *l++; } int read(){ int x=0,f=1;char ch=readc(); while (!isdigit(ch)) { if (ch=='-') f=-1; ch=readc();} while (isdigit(ch)) x=x*10+ch-48,ch=readc(); return x*f; } namespace splay { const int MAXN=100000+11; int fa[MAXN],ch[MAXN][2],val[MAXN],siz[MAXN],num[MAXN],root,cnt; void clear(int x) { fa[x]=val[x]=siz[x]=num[x]=ch[x][0]=ch[x][1]=0; } void update(int x) { siz[x]=(ch[x][0] ? siz[ch[x][0]]:0)+(ch[x][1] ? siz[ch[x][1]]:0)+num[x]; } int succ() { int x=ch[root][1]; while (ch[x][0]) x=ch[x][0]; return val[x]; } int succ_id() { int x=ch[root][1]; while (ch[x][0]) x=ch[x][0]; return x; } int pre() { int x=ch[root][0]; while (ch[x][1]) x=ch[x][1]; return val[x]; } int pre_id() { int x=ch[root][0]; while (ch[x][1]) x=ch[x][1]; return x; } void rotate(int x) { int y=fa[x],z=fa[y],d=(ch[y][1]==x); ch[y][d]=ch[x][d^1]; fa[ch[x][d^1]]=y; ch[x][d^1]=y; fa[y]=x,fa[x]=z; if (z)ch[z][ch[z][1]==y]=x; update(y); update(x); } void splay(int x) { for (int y; y=fa[x]; rotate(x)) if (fa[y]) rotate((x==ch[y][0])^(y==ch[fa[y]][0]) ? x:y); root=x; } int find_val(int x) { // 查询排名为 x 的数 int y=root,tmp; while (true) { if (ch[y][0]&&siz[ch[y][0]]>=x) y=ch[y][0]; else { tmp=(ch[y][0] ? siz[ch[y][0]]:0)+num[y]; if (x<=tmp) return val[y]; x-=tmp,y=ch[y][1]; } } } int find_rank(int x) { // 查询 x 数的排名 int y=root,tmp=0; while (true){ if (x<val[y]) y=ch[y][0]; else { tmp+=(ch[y][0] ? siz[ch[y][0]]:0); if (x==val[y]){ splay(y); return tmp+1; } tmp+=num[y],y=ch[y][1]; } } } void insert(int k) { int x=root; if (!x) { root=x=++cnt,ch[x][0]=ch[x][1]=fa[x]=0,val[x]=k,num[x]=siz[x]=1; return; } int y=x,z=0; while (true) { if (val[y]==k) { num[y]++;update(y),update(z);splay(y); break; } z=y,y=ch[y][val[y]<k]; if (!y) { val[y=++cnt]=k;num[y]=siz[y]=1;ch[y][0]=ch[y][1]=0;fa[y]=x;ch[x][val[x]<k]=y; break; } x=y; } splay(y); } void delt(int k) { find_rank(k); int x=root; if (!x) return; if (num[x]>1) { num[x]--,siz[x]--; return; } if (!ch[x][0]&&!ch[x][1]) { clear(x);root=0; return; } if (!ch[x][0]||!ch[x][1]) { int y=max(ch[x][0],ch[x][1]); root=y,fa[y]=0;clear(x); return; } int tmp=pre_id(); splay(tmp);fa[ch[x][1]]=tmp;ch[tmp][1]=ch[x][1];clear(x);update(tmp); } } using namespace splay; int main() { int n=read(); while (n--) { int opt=read(),x=read(); switch(opt) { case 1: insert(x); break; case 2: delt(x); break; case 3: printf("%d\n",find_rank(x)); break; case 4: printf("%d\n",find_val(x)); break; case 5: insert(x),printf("%d\n",pre()),delt(x); break; case 6: insert(x),printf("%d\n",succ()),delt(x); break; } } return 0; }