HDU 3487 Play with Chain (splay tree)

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 }

 

 

 

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/p/3283802.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞