Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) node
8 2 CUT 3 5 4 FLIP 2 6 -1 -1
【Sample Output】ios
1 4 3 7 6 2 5 8
【題意】算法
給出一列數,而後對整個數列執行兩種操做:切下一段插入到另外的位置,或者把其中的一整段整個翻轉一下。ide
求通過一系列操做以後,數列最後的樣子。this
【分析】spa
數據範圍最高可以到達3e5那麼大,所以算法至少要是O(nlogn)複雜度如下才可能達到要求。code
考慮採用Splay解決(這樣的題目只能用這種動態維護的樹結構不是麼?)orm
初始先建樹,把1~n加入Splay樹。因爲數列在後面是要被打亂順序的,Splay二叉平衡樹的性質只有在初始的時候是被保持的,以後是靠size,即每一個點在中序遍歷中的位置來維護。最後輸出數列則只須要中序遍歷一遍便可。blog
切割操做:若要切下a~b段,則把第a-1個結點移到根,把第b+1個結點移到根如下(即跟的右子樹),則整個a~b段就落在b+1的左子樹上,切出來。插入到c的時候,將c移到根,c+1移到根的右子樹,則切出來的插入到c+1的左子樹便可ip
翻轉操做:用上面相同的方法把a~b整合到一棵子樹上,而後能夠參考線段樹標記的方法,經過標記來完成訪問結點的翻轉等操做。
具體能夠在紙上模擬一下......
【教訓】
教訓仍是比較慘痛的...卡在這道題上很久了。
首先是輸入輸出之後要特別注意結尾方式,兩個負數結尾仍是兩個-1結尾
把各類可能出現的不一樣狀況考慮完整
1 /* *********************************************** 2 MYID : Chen Fan 3 LANG : G++ 4 PROG : HDU3487 5 ************************************************ */ 6 7 #include <iostream> 8 #include <cstdio> 9 #include <cstring> 10 #include <algorithm> 11 12 using namespace std; 13 14 #define MAXN 300010 15 16 int sons[MAXN][2]; 17 int father[MAXN],size[MAXN],data[MAXN],list[MAXN]; 18 bool flag[MAXN]; 19 int spt=0,spttail=0; 20 21 void down(int x) 22 { 23 if (flag[x]) 24 { 25 flag[x]=0; 26 swap(sons[x][0],sons[x][1]); 27 flag[sons[x][0]]^=1; 28 flag[sons[x][1]]^=1; 29 } 30 } 31 32 void rotate(int x,int w) //rotate(node,0/1) 33 { 34 int y=father[x]; 35 down(y);down(x); 36 sons[y][!w]=sons[x][w]; 37 if (sons[x][w]) father[sons[x][w]]=y; 38 39 father[x]=father[y]; 40 if (father[y]) sons[father[y]][y==sons[father[y]][1]]=x; 41 42 sons[x][w]=y; 43 father[y]=x; 44 45 size[x]=size[y]; 46 size[y]=size[sons[y][0]]+size[sons[y][1]]+1; 47 } 48 49 void splay(int x,int y) //splay(node,position) 50 { 51 down(x); 52 while(father[x]!=y) 53 { 54 if (father[father[x]]==y) rotate(x,x==sons[father[x]][0]); 55 else 56 { 57 int t=father[x]; 58 int w=(sons[father[t]][0]==t); 59 if (sons[t][w]==x) 60 { 61 rotate(x,!w); 62 rotate(x,w); 63 } else 64 { 65 rotate(t,w); 66 rotate(x,w); 67 } 68 } 69 } 70 if (!y) spt=x; 71 } 72 73 void select(int x,int v,int p) //select(root,k,position) 74 { 75 down(x); 76 while(v!=size[sons[x][0]]+1) 77 { 78 if (v<=size[sons[x][0]]) 79 { 80 x=sons[x][0]; 81 down(x); 82 } 83 else 84 { 85 v-=size[sons[x][0]]+1; 86 x=sons[x][1]; 87 down(x); 88 } 89 } 90 splay(x,p); 91 } 92 93 bool done=false; 94 95 void outp(int x) 96 { 97 down(x); 98 if (sons[x][0]) outp(sons[x][0]); 99 if (done) printf(" "); 100 done=true; 101 printf("%d",data[x]); 102 if (sons[x][1]) outp(sons[x][1]); 103 } 104 105 void maketree(int l,int r) 106 { 107 spttail++; 108 int now=spttail,w=(l+r)/2,ls=0,rs=0; 109 data[now]=w; 110 flag[now]=false; 111 sons[now][0]=0; 112 sons[now][1]=0; 113 114 if (l<=w-1) 115 { 116 ls=spttail+1; 117 sons[now][0]=ls; 118 father[ls]=now; 119 maketree(l,w-1); 120 } 121 if (w+1<=r) 122 { 123 rs=spttail+1; 124 sons[now][1]=rs; 125 father[rs]=now; 126 maketree(w+1,r); 127 } 128 129 size[now]=size[ls]+size[rs]+1; 130 } 131 132 int main() 133 { 134 freopen("3487.txt","r",stdin); 135 136 int n,m; 137 scanf("%d%d",&n,&m); 138 while(!(n<0&&m<0)) 139 { 140 spt=1; 141 spttail=0; 142 father[1]=0; 143 maketree(1,n); 144 145 for (int i=1;i<=m;i++) 146 { 147 char s[10]; 148 scanf("%s",&s); 149 if (s[0]=='C') 150 { 151 int a,b,c,temp; 152 scanf("%d%d%d",&a,&b,&c); 153 154 if (a>1) 155 { 156 select(spt,a-1,0); 157 if (b<n) 158 { 159 select(spt,b+1,spt); 160 temp=sons[sons[spt][1]][0]; 161 sons[sons[spt][1]][0]=0; 162 size[spt]-=size[temp]; 163 size[sons[spt][1]]-=size[temp]; 164 } else 165 { 166 temp=sons[spt][1]; 167 sons[spt][1]=0; 168 size[spt]-=size[temp]; 169 } 170 } else 171 { 172 if (b<n) 173 { 174 select(spt,b+1,0); 175 temp=sons[spt][0]; 176 sons[spt][0]=0; 177 size[spt]-=size[temp]; 178 } else temp=spt; 179 } 180 181 if (c>0) 182 { 183 select(spt,c,0); 184 if (c==size[spt]) 185 { 186 sons[spt][1]=temp; 187 father[temp]=spt; 188 size[spt]+=size[temp]; 189 } else 190 { 191 select(spt,c+1,spt); 192 sons[sons[spt][1]][0]=temp; 193 father[temp]=sons[spt][1]; 194 size[spt]+=size[temp]; 195 size[sons[spt][1]]+=size[temp]; 196 } 197 } else 198 { 199 if (spt!=temp) 200 { 201 select(spt,1,0); 202 sons[spt][0]=temp; 203 father[temp]=spt; 204 size[spt]+=size[temp]; 205 } 206 } 207 } else 208 { 209 int a,b,temp; 210 scanf("%d%d",&a,&b); 211 if (a>1) 212 { 213 select(spt,a-1,0); 214 if (b<n) 215 { 216 select(spt,b+1,spt); 217 temp=sons[sons[spt][1]][0]; 218 } else 219 { 220 temp=sons[spt][1]; 221 } 222 } else 223 { 224 if (b<n) 225 { 226 select(spt,b+1,0); 227 temp=sons[spt][0]; 228 } else temp=spt; 229 } 230 flag[temp]^=1; 231 } 232 } 233 done=false; 234 outp(spt); 235 printf("\n"); 236 scanf("%d%d",&n,&m); 237 } 238 239 return 0; 240 }