1. 程式人生 > >Shuffle Cards(牛客第三場+splay)

Shuffle Cards(牛客第三場+splay)

cstring urn tchar span insert push 圖片 題意 平衡

題目:

技術分享圖片

技術分享圖片

題意:將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 }

Shuffle Cards(牛客第三場+splay)