HDU 3487:Play with Chain(Splay)

时间:2021-08-20 08:23:54

http://acm.hdu.edu.cn/showproblem.php?pid=3487

题意:有两种操作:1、Flip l r ,把 l 到 r 这段区间 reverse。2、Cut a b c ,把 a 到 b 这段区间切掉,再把这段区间接到切掉后的第 c 个数的后面。

思路:做完了上一道变态题目,做这道题目如鱼得水。Cut的时候就是把a 到 b 放到keytree的位置,记录一下当前keytree的值,然后切掉,再把切掉后的第 c 个数转到 root 的位置,再把这个记录的值重新连接回去。要注意当全部询问结束了,要把所有的rev标记pushdown。

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <iostream>
#include <stack>
#include <map>
#include <queue>
using namespace std;
#define N 300100
#define INF 0x3f3f3f3f
#define lson ch[x][0]
#define rson ch[x][1]
#define keytree ch[ch[root][1]][0] struct SplayTree
{
int num[N], rev[N], ch[N][], fa[N], val[N], sz[N];
int n, root, cnt, ans[N], tol; void PushDown(int x)
{
if(rev[x]) {
swap(lson, rson);
if(lson) rev[lson] ^= ;
if(rson) rev[rson] ^= ;
rev[x] = ;
}
} void PushUp(int x)
{
sz[x] = sz[lson] + sz[rson] + ;
} int NewNode(int w, int f, int kind)
{
int x = ++cnt;
ch[x][] = ch[x][] = rev[x] = ;
sz[x] = ; val[x] = w; fa[x] = f;
ch[f][kind] = cnt;
return x;
} void Build(int l, int r, int &x, int f, int kind)
{
if(l > r) return ;
int m = (l + r) >> ;
x = NewNode(num[m], f, kind);
Build(l, m - , ch[x][], x, );
Build(m + , r, ch[x][], x, );
PushUp(x);
} void Init()
{
root = cnt = tol = ;
rev[] = val[] = fa[] = sz[] = ch[][] = ch[][] = ;
root = NewNode(, , );
ch[root][] = NewNode(, root, );
sz[root] = ;
Build(, n, keytree, ch[root][], );
PushUp(ch[root][]); PushUp(root);
} void Rotate(int x, int kind)
{
int y = fa[x], z = fa[y];
PushDown(y); PushDown(x);
ch[y][!kind] = ch[x][kind];
if(ch[y][!kind]) fa[ch[y][!kind]] = y;
if(z) {
if(y == ch[z][]) ch[z][] = x;
else ch[z][] = x;
}
fa[x] = z; fa[y] = x;
ch[x][kind] = y;
PushUp(y);
} void Splay(int x, int goal)
{
while(fa[x] != goal) {
int y = fa[x], z = fa[y];
PushDown(z); PushDown(y); PushDown(x);
int kind1 = x == ch[y][];
int kind2 = y == ch[z][];
if(z == goal) {
Rotate(x, kind1);
} else {
if(kind1 == kind2) {
Rotate(y, kind1);
} else {
Rotate(x, kind1);
}
Rotate(x, kind2);
}
}
PushUp(x);
if(goal == ) root = x;
} void RTO(int k, int goal)
{
int x = root;
PushDown(x);
while(k != sz[lson] + ) {
if(k <= sz[lson]) x = lson;
else k -= sz[lson] + , x = rson;
PushDown(x);
}
Splay(x, goal);
} void Cut(int l, int r, int c)
{
RTO(l, );
// Debug();
RTO(r + , root);
int tmp = keytree;
keytree = ;
// Debug();
RTO(c + , );
// Debug();
RTO(c + , root);
fa[tmp] = ch[root][];
keytree = tmp;
} void Reverse(int l, int r)
{
RTO(l, ); RTO(r + , root);
rev[keytree] ^= ;
} void Down(int x)
{
PushDown(x);
if(lson) Down(lson);
if(rson) Down(rson);
} void Travel(int x)
{
if(lson) Travel(lson);
ans[tol++] = val[x];
if(rson) Travel(rson);
} void Debug()
{
Down(root);
Travel(root);
for(int i = ; i <= n; i++) {
if(i == n) printf("%d\n", ans[i]);
else printf("%d ", ans[i]);
}
}
}spy; int main()
{
int n, m;
while(scanf("%d%d", &n, &m)) {
if(n < || m < ) break;
spy.n = n;
for(int i = ; i <= n; i++) spy.num[i] = i;
spy.Init();
while(m--) {
char s[];
int a, b, c;
scanf("%s", s);
if(s[] == 'C') {
scanf("%d%d%d", &a, &b, &c);
spy.Cut(a, b, c);
} else {
scanf("%d%d", &a, &b);
spy.Reverse(a, b);
}
}
spy.Debug();
}
return ;
}