再也不想写第二次。
题意:给一个n一个q 表示一开始有n个数 接下来q个操作 CUT a b c表示把[a, b]剪切到c处,FILP a b 将[a, b]区间翻转。
伸展树搞。 看的题解:点击打开链接
代码挺好理解的感觉。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <cstring>
#include <cstdlib>
#define value ch[ch[root][1]][0]
using namespace std;
const int maxn = 300000 + 7;
const int INF = ~0U >> 1;
int n, q;
int size[maxn], k[maxn], pre[maxn], rev[maxn];
int ch[maxn][2];
int tot = 0, root;
int cnt = 0;
void newNode(int &r, int key, int fa) {
r = ++tot;
ch[r][0] = ch[r][1] = 0;
pre[r] = fa;
rev[r] = 0;
k[r] = key;
}
void push_up(int r) {
size[r] = size[ch[r][0]] + size[ch[r][1]] + 1;
}
void push_down(int r) {
if(rev[r]) {
swap(ch[r][0], ch[r][1]);
rev[ch[r][0]] ^= 1;
rev[ch[r][1]] ^= 1;
rev[r] = 0;
}
}
void Build(int &r, int left, int right, int fa) {
if(left > right) return ;
int mid = (left + right) / 2;
newNode(r, mid, fa);
Build(ch[r][0], left, mid - 1, r);
Build(ch[r][1], mid + 1, right, r);
push_up(r);
}
void init() {
tot = root = cnt = 0;
ch[root][0] = ch[root][1] = 0;
pre[root] = size[root] = rev[root] = 0;
newNode(root, -1, 0);
newNode(ch[root][1], -1, root);
size[root] = 2;
Build(value, 1, n, ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
void Rotate(int x, int kind) {
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind]] = y;
if(pre[y]) ch[pre[y]][ch[pre[y]][1] == y] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
}
void splay(int r, int g) {
push_down(r);
while(pre[r] != g) {
if(pre[pre[r]] == g)
Rotate(r, ch[pre[r]][0] == r);
else {
int y = pre[r];
int kind = (ch[pre[y]][0] == y);
if(ch[y][kind] == r) {
Rotate(r, !kind);
Rotate(r, kind);
} else {
Rotate(y, kind);
Rotate(r, kind);
}
}
}
push_up(r);
if(g == 0) root = r;
}
int getKth(int r, int k) {
push_down(r);
int t = size[ch[r][0]];
if(t == k - 1) return r;
if(t >= k)
return getKth(ch[r][0], k);
else return getKth(ch[r][1], k - t - 1);
}
int getMin(int r) {
push_down(r);
while(ch[r][0]) {
r = ch[r][0];
push_down(r);
}
return r;
}
int getmax(int r) {
push_down(r);
while(ch[r][1]) {
r = ch[r][1];
push_down(r);
}
return r;
}
void reversal(int a, int b) {
int x = getKth(root, a);
int y = getKth(root,b + 2);
splay(x, 0);
splay(y, root);
rev[value] ^= 1;
}
void cut(int a, int b, int c) {
int x = getKth(root, a);
int y = getKth(root, b + 2);
splay(x, 0);
splay(y, root);
int temp = value;
value = 0;
push_up(ch[root][1]);
push_up(root);
int z = getKth(root, c + 1);
splay(z, 0);
int m = getMin(ch[root][1]);
splay(m,root);
value = temp;
pre[value] = ch[root][1];
push_up(ch[root][1]);
push_up(root);
}
void print(int r) {
if(!r) return ;
push_down(r);
print(ch[r][0]);
if(cnt >= 1 && cnt <= n) {
if(cnt > 1) printf(" ");
printf("%d", k[r]);
}
++cnt;
print(ch[r][1]);
}
int main() {
while(scanf("%d%d", &n, &q) != EOF) {
if(n == -1 && q == -1) break;
init();
while(q--) {
char s[5] = {0};
int a, b, c;
scanf("%s", s);
if(s[0] == 'C') {
scanf("%d%d%d", &a, &b, &c);
//cout << a << b << c << "==" << endl;
cut(a, b, c);
} else {
scanf("%d%d", &a, &b);
reversal(a, b);
}
}
print(root);
printf("\n");
}
return 0;
}