题目链接:hdu 4453 Looploop
题意:具体看看图,都是splay的基本操作,当然不用splay也可以,这题有特殊性。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5 const int N=1e6+7; 6 int _t; 7 int n,m,k1,k2,a[N],cas; 8 char cmd[10]; 9 10 struct Splay_tree 11 { 12 int root,q[N];bool rev[N]; 13 int key[N],sz[N],f[N],ch[N][2],add[N]; 14 void init(){root=0;}//初始化为一棵空树 15 void rev1(int x){if(x)swap(ch[x][0],ch[x][1]),rev[x]^=1;} 16 void add1(int x,int p){if(x)key[x]+=p,add[x]+=p;} 17 inline void nw(int &x,int val,int fa) 18 { 19 x=++_t,key[x]=a[val],f[x]=fa,sz[x]=1; 20 ch[x][0]=ch[x][1]=0; 21 add[x]=rev[x]=0; 22 } 23 inline void pd(int x) 24 { 25 if(add[x])add1(ch[x][0],add[x]),add1(ch[x][1],add[x]),add[x]=0; 26 if(rev[x])rev1(ch[x][0]),rev1(ch[x][1]),rev[x]=0; 27 } 28 inline void up(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;} 29 void rotate(int x){ 30 int y=f[x],w=ch[y][1]==x; 31 ch[y][w]=ch[x][w^1]; 32 if(ch[x][w^1])f[ch[x][w^1]]=y; 33 if(f[y]){ 34 int z=f[y]; 35 if(ch[z][0]==y)ch[z][0]=x; 36 if(ch[z][1]==y)ch[z][1]=x; 37 } 38 f[x]=f[y],ch[x][w^1]=y,f[y]=x,up(y); 39 } 40 41 void splay(int x,int w){ 42 int s=1,i=x,y;q[1]=x; 43 while(f[i])q[++s]=i=f[i]; 44 while(s)pd(q[s--]); 45 while(f[x]!=w){ 46 y=f[x]; 47 if(f[y]!=w){if((ch[f[y]][0]==y)^(ch[y][0]==x))rotate(x);else rotate(y);} 48 rotate(x); 49 } 50 if(!w)root=x; 51 up(x); 52 } 53 void build(int &x,int l,int r,int fa=0)//按照数组下标建树 54 { 55 if(l>r)return; 56 int mid=l+r>>1; 57 nw(x,mid,fa); 58 build(ch[x][0],l,mid-1,x); 59 build(ch[x][1],mid+1,r,x); 60 up(x); 61 } 62 inline int find(int _key) //返回值为key的节点 若无返回0 若有将其转移到根处 63 { 64 if(!root)return 0; 65 int x=root; 66 for(pd(x);x&&key[x]!=_key;)x=ch[x][key[x]<_key]; 67 if(x)splay(x,0); 68 return x; 69 } 70 inline void Delete(int pos)//删除下标为r的节点 71 { 72 //splay(r,0); 73 //int pos=sz[ch[r][0]]; 74 splay(kth(pos),0); 75 splay(kth(pos+2),root); 76 ch[ch[root][1]][0]=0; 77 up(ch[root][1]),up(root); 78 } 79 inline int kth(int k)//获得第k小 80 { 81 if(k>sz[root]||k<=0)return 0; 82 int x=root,tmp; 83 while(1) 84 { 85 pd(x),tmp=sz[ch[x][0]]+1; 86 if(k==tmp)break; 87 if(k<tmp)x=ch[x][0];else k-=tmp,x=ch[x][1]; 88 } 89 return x; 90 } 91 void reverse(int a,int b)//翻转a到b区间 92 { 93 splay(kth(a),0),splay(kth(b+2),root); 94 rev1(ch[ch[root][1]][0]); 95 } 96 inline void ins(int _key)//插入key键值 97 { 98 if(!root){nw(root,_key,0);return;} 99 int x=root,y=0; 100 while(x)pd(x),y=x,sz[x]++,x=ch[x][key[x]<_key]; 101 nw(ch[y][key[y]<_key],_key,y); 102 splay(ch[y][key[y]<_key],0); 103 } 104 void cut(int a,int b,int c) 105 { 106 splay(kth(a),0),splay(kth(b+2),root); 107 int tmp=ch[ch[root][1]][0]; 108 ch[ch[root][1]][0]=0; 109 pd(ch[root][1]),pd(root); 110 splay(kth(c+1),0); 111 splay(kth(c+2),root); 112 ch[ch[root][1]][0]=tmp; 113 f[ch[ch[root][1]][0]]=ch[root][1]; 114 up(ch[root][1]),up(root); 115 } 116 void inorder(int r)//按顺序输出 117 { 118 if(!r)return; 119 inorder(ch[r][0]); 120 printf("%d ",key[r]); 121 inorder(ch[r][1]); 122 } 123 }spt; 124 //-------------------------------- 125 126 int main() 127 { 128 while(scanf("%d%d%d%d",&n,&m,&k1,&k2),n+m+k1+k2) 129 { 130 int x,y; 131 F(i,1,n)scanf("%d",a+i); 132 spt.build(spt.root,0,n+1); 133 printf("Case #%d: ",++cas); 134 F(i,1,m) 135 { 136 scanf("%s",cmd); 137 if(cmd[0]=='a') 138 { 139 scanf("%d",&x); 140 spt.splay(spt.kth(1),0); 141 spt.splay(y=spt.kth(k2+2),spt.root); 142 spt.add1(spt.ch[y][0],x); 143 }else if(cmd[0]=='r') 144 { 145 spt.splay(spt.kth(1),0); 146 spt.splay(y=spt.kth(k1+2),spt.root); 147 spt.rev1(spt.ch[y][0]); 148 }else if(cmd[0]=='i') 149 { 150 scanf("%d",&x); 151 spt.splay(spt.kth(2),0); 152 spt.splay(y=spt.kth(3),spt.root); 153 ++_t,spt.key[_t]=x,spt.f[_t]=y,spt.sz[_t]=1; 154 spt.ch[_t][0]=spt.ch[_t][1]=0; 155 spt.add[_t]=spt.rev[_t]=0,spt.ch[y][0]=_t; 156 n++; 157 }else if(cmd[0]=='d') 158 { 159 spt.Delete(1); 160 n--; 161 }else if(cmd[0]=='m') 162 { 163 scanf("%d",&x); 164 if(x==1) 165 { 166 spt.cut(n,n,0); 167 }else 168 { 169 spt.cut(1,1,n-1); 170 } 171 }else 172 { 173 x=spt.kth(2); 174 printf("%d ",spt.key[x]); 175 } 176 } 177 } 178 return 0; 179 }