Shuffle Cards(牛客第三场+splay)

题目:

题意:将1~n的数进行m次操作,每次操作将第pi位到pi+si-1位的数字移到第一位,求最后的排列。

思路:现在还没不会写splay,在知道这是splay模板题后找了一波别人的模板,虽然过了,但是感觉自己没学到什么,过几天去学一波splay,再回来把这题重写一次~

代码实现如下:

  1 #include <map>
  2 #include <set>
  3 #include <cmath>
  4 #include <ctime>
  5 #include <stack>
  6 #include <queue>
  7 #include <cstdio>
  8 #include <cctype>
  9 #include <bitset>
 10 #include <string>
 11 #include <vector>
 12 #include <cstring>
 13 #include <iostream>
 14 #include <algorithm>
 15 #include <functional>
 16 #include <bits/stdc++.h>
 17 #define debug(x) cout<<"["<<x<<"]";
 18 #define FIN freopen("input.txt","r",stdin);
 19 #define FOUT freopen("output.txt","w+",stdout);
 20 
 21 inline int read() {//读入挂
 22     int ret = 0, c, f = 1;
 23     for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
 24     if(c == '-')
 25         f = -1, c = getchar();
 26     for(; isdigit(c); c = getchar())
 27         ret = ret * 10 + c - '0';
 28     if(f < 0)
 29         ret = -ret;
 30     return ret;
 31 }
 32 
 33 const int MX = 1e5 + 7;
 34 const int INF = 0x3f3f3f3f;
 35 
 36 int size[MX];
 37 int num[MX], col[MX], n, m;
 38 int son[MX][2], fa[MX], root, sz;
 39 void Link(int x, int y, int c) {
 40     fa[x] = y;
 41     son[y][c] = x;
 42 }
 43 void push_up(int rt) {
 44     size[rt] = size[son[rt][0]] + size[son[rt][1]] + 1;
 45 }
 46 void push_down(int rt) {
 47     if(col[rt]) {
 48         col[son[rt][0]] ^= 1;
 49         col[son[rt][1]] ^= 1;
 50         int x = son[rt][0];
 51         son[rt][0] = son[rt][1];
 52         son[rt][1] = x;
 53         col[rt] = 0;
 54     }
 55 }
 56 void Rotate(int x, int c) {
 57     int y = fa[x];
 58     push_down(y);
 59     push_down(x);
 60     Link(x, fa[y], son[fa[y]][1] == y);
 61     Link(son[x][!c], y, c);
 62     Link(y, x, !c);
 63     push_up(y);
 64 } /*把节点x旋转到g的下面*/
 65 
 66 void Splay(int x, int g) {
 67     push_down(x);    /*剪断[a,b]放到c后面*/
 68     while(fa[x] != g) {
 69         int y = fa[x], cx = son[y][1] == x, cy = son[fa[y]][1] == y;
 70         if(fa[y] == g)
 71             Rotate(x, cx);
 72         else {
 73             if(cx == cy)
 74                 Rotate(y, cy);
 75             else
 76                 Rotate(x, cx);
 77             Rotate(x, cy);
 78         }
 79     }
 80     push_up(x);
 81     if(!g)
 82         root = x;
 83 }
 84 void NewNode(int f, int &rt) {
 85     rt = ++sz;
 86     fa[rt] = f, size[rt] = 1;
 87     son[rt][0] = son[rt][1] = col[rt] = 0;
 88 } /*把第k个找出来,放到g的下面*/ int Select(int k, int g) {
 89     int rt = root;
 90     while(size[son[rt][0]] != k) {
 91         if(size[son[rt][0]] > k)
 92             rt = son[rt][0];
 93         else
 94             k -= size[son[rt][0]] + 1, rt = son[rt][1];
 95         push_down(rt);
 96     }
 97     Splay(rt, g);
 98     return rt;
 99 }
100 void Build(int l, int r, int &rt, int f) {
101     if(l > r)
102         return;
103     int m = (l + r) >> 1, t;
104     NewNode(f, rt);
105     num[rt] = m;
106     Build(l, m - 1, son[rt][0], rt);
107     Build(m + 1, r, son[rt][1], rt);
108     push_up(rt);
109 }
110 void Prepare(int n) {
111     sz = 0;
112     NewNode(0, root);
113     num[1] = 0;
114     NewNode(root, son[root][1]);
115     num[2] = 0;
116     Build(1, n, son[2][0], 2);
117     Splay(3, 0);
118 }
119 void Print(int rt, int &DFN) {
120     if(!rt)
121         return;
122     push_down(rt);
123     Print(son[rt][0], DFN);
124     if(num[rt])
125         printf("%d%c", num[rt], ++DFN == n ? '\n' : ' ');
126     Print(son[rt][1], DFN);
127 }
128 void Flip(int l, int r) {
129     Select(l - 1, 0);
130     Select(r + 1, root);
131     col[son[son[root][1]][0]] ^= 1;
132 }
133 
134 void Cut(int a, int b, int c) {
135     Select(a - 1, 0);    /*平衡树操作*/
136     Select(b + 1, root);
137     int w = son[son[root][1]][0];
138     son[son[root][1]][0] = 0;
139     Splay(son[root][1], 0);
140     Select(c, 0);
141     Select(c + 1, root);
142     son[son[root][1]][0] = w;
143     Splay(son[root][1], 0);
144 }
145 void NewNode(int f, int x, int &rt) {
146     rt = ++sz;
147     fa[rt] = f, size[rt] = 1;
148     son[rt][0] = son[rt][1] = 0;
149     num[rt] = x;
150 }
151 int Kth(int k) {
152     int rt = root;
153     while(size[son[rt][0]] != k) {
154         if(size[son[rt][0]] > k)
155             rt = son[rt][0];
156         else
157             k -= size[son[rt][0]] + 1, rt = son[rt][1];
158     }
159     Splay(rt, 0);
160     return num[rt];
161 }
162 void Insert(int x) {
163     int rt = root;
164     while(true) {
165         int nxt = x > num[rt];
166         if(!son[rt][nxt]) {
167             NewNode(rt, x, son[rt][nxt]);
168             Splay(sz, 0);
169             return;
170         }
171         rt = son[rt][nxt];
172     }
173 }
174 
175 
176 int main() {
177     while(~scanf("%d%d", &n, &m)) {
178         Prepare(n);
179         int x, y;
180         for(int i = 0; i < m; i++) {
181             scanf("%d%d", &x, &y);
182             Cut(x, x + y - 1, 0);
183         }
184         int DFN = 0;
185         Print(root, DFN);
186     }
187     return 0;
188 }

猜你喜欢

转载自www.cnblogs.com/Dillonh/p/9373653.html