fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架
题解:记录每本书对应的节点编号
普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中),
查询时从该节点开始逐步往上跳,记录答案。
其他操作都依附在该排名上。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<cstdlib> 5 using namespace std; 6 inline int rd(){ 7 int x=0,f=1;char c=getchar(); 8 while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} 9 while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} 10 return f*x; 11 } 12 const int maxn=(8e4)+50; 13 int N,M,lc[maxn],rc[maxn],val[maxn],pr[maxn],tot=0,siz[maxn]; 14 int u,rt=0,s,t,x,y,z,id[maxn],fa[maxn],k; 15 //id[i]表示编号为i的书所在的节点编号 16 char o[15]; 17 inline int New_node(int x){ 18 val[++tot]=x; 19 siz[tot]=1; 20 pr[tot]=rand(); 21 return tot; 22 } 23 inline void Pushup(int x){ 24 siz[x]=siz[lc[x]]+siz[rc[x]]+1; 25 fa[lc[x]]=fa[rc[x]]=x; 26 return; 27 } 28 inline void Split(int now,int k,int &x,int &y){ 29 if(!now){ 30 x=y=fa[x]=fa[y]=0; 31 return; 32 } 33 if(siz[lc[now]]+1<=k){ 34 x=now; 35 Split(rc[now],k-siz[lc[now]]-1,rc[now],y); 36 } 37 else { 38 y=now; 39 Split(lc[now],k,x,lc[now]); 40 } 41 Pushup(now); 42 return; 43 } 44 inline int Merge(int x,int y){ 45 if(!x||!y){ 46 fa[x]=fa[y]=x+y; 47 return x+y; 48 } 49 if(pr[x]<pr[y]){ 50 rc[x]=Merge(rc[x],y); 51 Pushup(x); 52 return x; 53 } 54 else{ 55 lc[y]=Merge(x,lc[y]); 56 Pushup(y); 57 return y; 58 } 59 } 60 inline int Find(int x){//寻找x节点上有多少书 61 int sum=0; 62 sum+=siz[lc[x]]; 63 while(x!=rt){ 64 if(rc[fa[x]]==x)sum+=siz[lc[fa[x]]]+1; 65 x=fa[x]; 66 } 67 return sum; 68 } 69 inline int Query(int k){ 70 int now=rt; 71 while(now){ 72 if(k<=siz[lc[now]])now=lc[now]; 73 else if(k==siz[lc[now]]+1)return now; 74 else k-=siz[lc[now]]+1,now=rc[now]; 75 } 76 return 0; 77 } 78 int main(){ 79 srand(20030304); 80 N=rd();M=rd(); 81 for(int i=1;i<=N;i++){ 82 u=rd(); 83 rt=Merge(rt,id[u]=New_node(u)); 84 } 85 while(M--){ 86 scanf("%s",o); s=rd(); 87 if(o[0]=='T'){ 88 k=Find(id[s]); 89 Split(rt,k+1,x,z); 90 Split(x,k,x,y); 91 rt=Merge(Merge(x,Merge(lc[y],rc[y])),z); 92 rt=Merge(id[s],rt); 93 } 94 else if(o[0]=='B'){ 95 k=Find(id[s]); 96 Split(rt,k+1,x,z); 97 Split(x,k,x,y); 98 rt=Merge(Merge(x,Merge(lc[y],rc[y])),z); 99 rt=Merge(rt,id[s]); 100 } 101 else if(o[0]=='I'){ 102 t=rd(); 103 k=Find(id[s]); 104 Split(rt,k+1,x,z); 105 Split(x,k,x,y); 106 rt=Merge(Merge(x,Merge(lc[y],rc[y])),z); 107 Split(rt,k+t,x,y); 108 rt=Merge(Merge(x,id[s]),y); 109 } 110 else if(o[0]=='A'){ 111 printf("%d\n",Find(id[s])); 112 } 113 else {//Q 114 printf("%d\n",val[Query(s)]); 115 } 116 } 117 return 0; 118 }
By:AlenaNuna