【题目链接】
【思路要点】
- 使用可以打标记的Splay来实现区间翻转,时间复杂度\(O(MLogN)\)。
- 代码过于陈旧,风格较丑。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 100005 struct Node { int father, child[2], size, value; bool rev; }; Node a[MAXN]; int n, m, size, root; bool printed; bool get(int x) { return a[a[x].father].child[1] == x; } void update(int x) { if (x == 0) return; a[x].size = 1; if (a[x].child[0]) a[x].size += a[a[x].child[0]].size; if (a[x].child[1]) a[x].size += a[a[x].child[1]].size; } void pushdown(int x) { if (a[x].rev == false) return; swap(a[x].child[0], a[x].child[1]); if (a[x].child[0]) a[a[x].child[0]].rev ^= true; if (a[x].child[1]) a[a[x].child[1]].rev ^= true; a[x].rev = false; } void rotate(int x) { int f = a[x].father, g = a[f].father; pushdown(f); pushdown(x); int tmp = get(x); a[f].child[tmp] = a[x].child[tmp ^ 1]; a[a[x].child[tmp ^ 1]].father = f; a[f].father = x; a[x].child[tmp ^ 1] = f; a[x].father = g; if (g) a[g].child[a[g].child[1] == f] = x; update(f); update(x); } void splay(int x) { for (int f = a[x].father; f = a[x].father; rotate(x)) if (a[f].father) rotate(get(x) == get(f) ? f : x); root = x; } void splayII(int x) { for (int f = a[x].father; (f = a[x].father) != root; rotate(x)) if (a[f].father != root) rotate(get(x) == get(f) ? f : x); } void insert(int x) { int now = root; while (true) { pushdown(now); if (a[now].child[1]) now = a[now].child[1]; else { a[now].child[1] = ++size; a[size].father = now; a[size].size = 1; a[size].value = x; splay(size); return; } } } int find(int x) { int now = root; while (true) { pushdown(now); if (x <= a[a[now].child[0]].size) now = a[now].child[0]; else { x -= a[a[now].child[0]].size; if (x == 1) return now; x--; now = a[now].child[1]; } } } void get_interval(int x, int y) { splay(find(x)); splayII(find(y)); } void print(int x) { if (x == 0) return; pushdown(x); print(a[x].child[0]); if (a[x].value) if (printed) printf(" %d", a[x].value); else { printf("%d", a[x].value); printed = true; } print(a[x].child[1]); } int main() { scanf("%d%d", &n, &m); root = size = 1; a[1].value = 0; a[1].size = 1; for (int i = 1; i <= n; i++) insert(i); insert(0); for (int i = 1; i <= m; i++) { int x, y; scanf("%d%d", &x, &y); get_interval(x, y + 2); a[a[a[root].child[1]].child[0]].rev ^= true; } print(root); printf(" "); return 0; }