2018牛客多校第三场 C.Shuffle Cards
题意:
给出一段序列,每次将从第p个数开始的s个数移到最前面。求最终的序列是什么。
题解:
Splay翻转模板题。存下板子。
#include <bits/stdc++.h> using namespace std; const int INF = 1e6; const int N = 1e5+10; int n, m; int s, t; int root, sz, tot; int key[N], f[N], size[N], delta[N], cnt[N], ch[N][2]; int a[N], ans[N]; int get(int x) { return ch[f[x]][1] == x; } void update(int x) { if(x) { size[x] = cnt[x]; if(ch[x][0]) size[x] += size[ch[x][0]]; if(ch[x][1]) size[x] += size[ch[x][1]]; } } int build(int l, int r, int fa) { if (l > r) return 0; int mid = l+r>>1; int now = ++sz; key[now] = a[mid]; f[now] = fa; cnt[now] = 1; int lch = build(l, mid-1, now); int rch = build(mid+1, r, now); ch[now][0] = lch, ch[now][1] = rch; update(now); return now; } void pushdown(int x) { if(x && delta[x]) { swap(ch[x][0], ch[x][1]); delta[ch[x][0]] ^= 1; delta[ch[x][1]] ^= 1; delta[x] = 0; } } void rotate(int x) { pushdown(f[x]); pushdown(x); int old = f[x], oldf = f[old], which = get(x); ch[old][which] = ch[x][which^1]; f[ch[old][which]] = old; f[old] = x; ch[x][which^1] = old; f[x] = oldf; if(oldf) ch[oldf][ch[oldf][1]==old] = x; update(old); update(x); } void splay(int x, int tar) { for(int fa; (fa = f[x])!=tar; rotate(x)) if(f[fa] != tar) rotate((get(x)==get(fa))?fa:x); if(!tar) root = x; } int find(int x) { int now = root, fa = 0; while(1) { pushdown(now); if(x <= size[ch[now][0]]) now = ch[now][0]; else { x -= size[ch[now][0]]+1; if(x == 0) return now; now = ch[now][1]; } } } void print(int now) { pushdown(now); if(ch[now][0]) print(ch[now][0]); if(key[now]!=-INF && key[now]!=INF) ans[++tot] = key[now]; if(ch[now][1]) print(ch[now][1]); } int main() { scanf("%d%d", &n, &m); a[1] = -INF; a[n+2] = INF; for(int i = 2; i <= n+1; i++) a[i] = i-1; root = build(1, n+2, 0); while(m--) { scanf("%d%d", &s, &t); if(s == 1) continue; int f1 = find(1); int f2 = find(s+t+1); splay(f1, 0); splay(f2, f1); delta[ch[ch[root][1]][0]] ^= 1; f2 = find(t+2); splay(f2, f1); delta[ch[ch[root][1]][0]] ^= 1; f1 = find(t+1); f2 = find(s+t+1); splay(f1, 0); splay(f2, f1); delta[ch[ch[root][1]][0]]^=1; } print(root); for(int i = 1; i < n; i++) printf("%d ", ans[i]); printf("%d\n", ans[n]); }