题面
https://www.luogu.org/problem/P3835
题解
#include<cstdio> #include<cstdlib> #include<iostream> #include<ctime> using namespace std; struct fhq_treap { int v[500050*50],fix[500050*50],ch[500050*50][2],siz[500050*50]; int root[500050],cnt; void clear() {cnt=0;} void copy(int x,int y) { v[y]=v[x]; fix[y]=fix[x]; ch[y][0]=ch[x][0]; ch[y][1]=ch[x][1]; siz[y]=siz[x]; } void update(int x) { siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; } void split(int k,int x,int y,int &ch1,int &ch2) { if (!x) { ch2=ch1=0; return; } copy(x,y); if (v[y]<=k) { ch1=y; split(k,ch[y][1],++cnt,ch[y][1],ch2); } else { ch2=y; split(k,ch[y][0],++cnt,ch1,ch[y][0]); } update(y); } int merge(int x,int y) { if (!x || !y) return x+y; if (fix[x]<fix[y]) { ch[x][1]=merge(ch[x][1],y); update(x); return x; } else { ch[y][0]=merge(x,ch[y][0]); update(y); return y; } } int newnode(int val) { ++cnt; v[cnt]=val; fix[cnt]=rand(); siz[cnt]=1; return cnt; } void insert(int his,int cur,int val) { int root1=0,root2=0; split(val,root[his],++cnt,root1,root2); root[cur]=merge(merge(root1,newnode(val)),root2); } void erase(int his,int cur,int val) { int root1=0,root2=0,root3=0; split(val,root[his],++cnt,root1,root3); split(val-1,root1,++cnt,root1,root2); root2=merge(ch[root2][0],ch[root2][1]); root[cur]=merge(merge(root1,root2),root3); } int findkth(int k,int his,int cur) { int now=root[cur]=root[his]; int rk=1; while (now) { if (siz[ch[now][0]]+rk==k) return v[now]; else if (siz[ch[now][0]]+rk>k) now=ch[now][0]; else rk+=siz[ch[now][0]]+1,now=ch[now][1]; } return -1; } int findrank(int k,int his,int cur) { int root1=0,root2=0; split(k-1,root[his],++cnt,root1,root2); int ret=siz[root1]+1; root[cur]=merge(root1,root2); return ret; } int findpre(int k,int his,int cur) { int pre=-2147483647; int now=root[cur]=root[his]; while (now) { if (v[now]<k) pre=max(pre,v[now]),now=ch[now][1]; else now=ch[now][0]; } return pre; } int findsuc(int k,int his,int cur) { int suc=2147483647; int now=root[cur]=root[his]; while (now) { if (v[now]>k) suc=min(suc,v[now]),now=ch[now][0]; else now=ch[now][1]; } return suc; } } treap; int n; int main() { int i,his,opt,x; srand(time(0)); treap.clear(); scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%d %d %d",&his,&opt,&x); if (opt==1) treap.insert(his,i,x); if (opt==2) treap.erase(his,i,x); if (opt==3) printf("%d ",treap.findrank(x,his,i)); if (opt==4) printf("%d ",treap.findkth(x,his,i)); if (opt==5) printf("%d ",treap.findpre(x,his,i)); if (opt==6) printf("%d ",treap.findsuc(x,his,i)); } return 0; }