Play with Chain
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2783 Accepted Submission(s): 1141
Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.
At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.
He will perform two types of operations:
CUT a b c: He will first cut down the chain from the ath diamond to the bth diamond. And then insert it after the cth diamond on the remaining chain.
For example, if n=8, the chain is: 1 2 3 4 5 6 7 8; We perform “CUT 3 5 4”, Then we first cut down 3 4 5, and the remaining chain would be: 1 2 6 7 8. Then we insert “3 4 5” into the chain before 5th diamond, the chain turns out to be: 1 2 6 7 3 4 5 8.
FLIP a b: We first cut down the chain from the ath diamond to the bth diamond. Then reverse the chain and put them back to the original position.
For example, if we perform “FLIP 2 6” on the chain: 1 2 6 7 3 4 5 8. The chain will turn out to be: 1 4 3 7 6 2 5 8
He wants to know what the chain looks like after perform m operations. Could you help him?
Input There will be multiple test cases in a test data.
For each test case, the first line contains two numbers: n and m (1≤n, m≤3*100000), indicating the total number of diamonds on the chain and the number of operations respectively.
Then m lines follow, each line contains one operation. The command is like this:
CUT a b c // Means a CUT operation, 1 ≤ a ≤ b ≤ n, 0≤ c ≤ n-(b-a+1).
FLIP a b // Means a FLIP operation, 1 ≤ a < b ≤ n.
The input ends up with two negative numbers, which should not be processed as a case.
Output For each test case, you should print a line with n numbers. The ith number is the number of the ith diamond on the chain.
Sample Input 8 2 CUT 3 5 4 FLIP 2 6 -1 -1
Sample Output 1 4 3 7 6 2 5 8
Source
2010 ACM-ICPC Multi-University Training Contest(5)——Host by BJTU
Recommend zhengfeng
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013/8/25 23:35:30 4 File Name :F:\2013ACM练习\专题学习\splay_tree_2\HDU3487.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 21 #define Key_value ch[ch[root][1]][0] 22 const int MAXN = 300010; 23 int pre[MAXN],ch[MAXN][2],root,tot1; 24 int key[MAXN],rev[MAXN]; 25 int size[MAXN]; 26 int s[MAXN],tot2; 27 int n,q; 28 29 void NewNode(int &r,int father,int k) 30 { 31 if(tot2) r = s[tot2--]; 32 else r = ++tot1; 33 key[r] = k; 34 pre[r] = father; 35 rev[r] = 0; 36 ch[r][0] = ch[r][1] = 0; 37 size[r] = 1; 38 } 39 //反转的更新 40 void Update_Rev(int r) 41 { 42 if(!r) return; 43 swap(ch[r][0],ch[r][1]); 44 rev[r] ^= 1; 45 } 46 void push_up(int r) 47 { 48 size[r] = size[ch[r][0]] + size[ch[r][1]] + 1; 49 } 50 void push_down(int r) 51 { 52 if(rev[r]) 53 { 54 Update_Rev(ch[r][0]); 55 Update_Rev(ch[r][1]); 56 rev[r] = 0; 57 } 58 } 59 60 void Build(int &x,int l,int r,int father) 61 { 62 if(l > r)return; 63 int mid = (l+r)/2; 64 NewNode(x,father,mid); 65 Build(ch[x][0],l,mid-1,x); 66 Build(ch[x][1],mid+1,r,x); 67 push_up(x); 68 } 69 void Init() 70 { 71 root = tot1 = tot2 = 0; 72 ch[root][0] = ch[root][1] = size[root] = key[root] = pre[root] = rev[root] = 0; 73 NewNode(root,0,-1); 74 NewNode(ch[root][1],root,-1); 75 Build(Key_value,1,n,ch[root][1]); 76 push_up(ch[root][1]); 77 push_up(root); 78 } 79 void Rotate(int x,int kind) 80 { 81 int y = pre[x]; 82 push_down(y); 83 push_down(x); 84 ch[y][!kind] = ch[x][kind]; 85 pre[ch[x][kind]] = y; 86 if(pre[y]) 87 ch[pre[y]][ch[pre[y]][1]==y] = x; 88 pre[x] = pre[y]; 89 ch[x][kind] = y; 90 pre[y] = x; 91 push_up(y); 92 } 93 void Splay(int r,int goal) 94 { 95 push_down(r); 96 while(pre[r] != goal) 97 { 98 if(pre[pre[r]] == goal) 99 { 100 push_down(pre[r]); 101 push_down(r); 102 Rotate(r,ch[pre[r]][0]==r); 103 } 104 else 105 { 106 push_down(pre[pre[r]]); 107 push_down(pre[r]); 108 push_down(r); 109 int y = pre[r]; 110 int kind = ch[pre[y]][0]==y; 111 if(ch[y][kind] == r) 112 { 113 Rotate(r,!kind); 114 Rotate(r,kind); 115 } 116 else 117 { 118 Rotate(y,kind); 119 Rotate(r,kind); 120 } 121 } 122 } 123 push_up(r); 124 if(goal == 0)root = r; 125 } 126 int Get_kth(int r,int k) 127 { 128 push_down(r); 129 int t = size[ch[r][0]] + 1; 130 if(t == k)return r; 131 if(t > k)return Get_kth(ch[r][0],k); 132 else return Get_kth(ch[r][1],k-t); 133 } 134 //将[l,r]段剪切下来,放在剩下段的第c个后面 135 void CUT(int l,int r,int c) 136 { 137 Splay(Get_kth(root,l),0); 138 Splay(Get_kth(root,r+2),root); 139 int tmp = Key_value; 140 Key_value = 0; 141 push_up(ch[root][1]); 142 push_up(root); 143 Splay(Get_kth(root,c+1),0); 144 Splay(Get_kth(root,c+2),root); 145 Key_value = tmp; 146 pre[Key_value] = ch[root][1]; 147 push_up(ch[root][1]); 148 push_up(root); 149 } 150 //将[l,r]段反转 151 void FLIP(int l,int r) 152 { 153 Splay(Get_kth(root,l),0); 154 Splay(Get_kth(root,r+2),root); 155 Update_Rev(Key_value); 156 push_up(ch[root][1]); 157 push_up(root); 158 } 159 //按顺序输出 160 int cnt; 161 void InOrder(int r) 162 { 163 if(!r)return; 164 push_down(r); 165 InOrder(ch[r][0]); 166 if(cnt >=1 && cnt <= n) 167 { 168 printf("%d",key[r]); 169 if(cnt < n)printf(" "); 170 else printf("\n"); 171 } 172 cnt++; 173 InOrder(ch[r][1]); 174 } 175 int main() 176 { 177 //freopen("in.txt","r",stdin); 178 //freopen("out.txt","w",stdout); 179 while(scanf("%d%d",&n,&q) == 2) 180 { 181 if( n < 0 && q < 0)break; 182 Init(); 183 char op[20]; 184 int x,y,z; 185 while(q--) 186 { 187 scanf("%s",op); 188 if(op[0] == 'C') 189 { 190 scanf("%d%d%d",&x,&y,&z); 191 CUT(x,y,z); 192 } 193 else 194 { 195 scanf("%d%d",&x,&y); 196 FLIP(x,y); 197 } 198 } 199 cnt = 0; 200 InOrder(root); 201 } 202 return 0; 203 }