Splay的基础操作。
1、删除某一个区间,然后从某个位置插入,可以将其旋转到关键树上去然后删掉就行了
2、旋转某个区间。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define keytree (ch[ ch[root][1] ][0])
using namespace std;
const int SIZEN = 300005;
struct SplayTree{
int ch[SIZEN][2];
int pre[SIZEN];
int sz[SIZEN];
int top,root,cnt,n;
inline void pushup(int x){
sz[x] = sz[ ch[x][0] ] + sz[ ch[x][1] ] + 1;
}
inline void change(int x){
swap(ch[x][0],ch[x][1]);
}
inline void pushdown(int x){
if(lazy[x]){
lazy[ ch[x][0] ] ^= 1;
lazy[ ch[x][1] ] ^= 1;
change(ch[x][0]);
change(ch[x][1]);
lazy[x] = 0;
}
}
void Travel(int x){
pushdown(x);
if(ch[x][0]) Travel(ch[x][0]);
printf("node:%d lson:%d rson:%d pre:%d val:%d sz:%d\n",x,ch[x][0],ch[x][1],pre[x],val[x],sz[x]);
if(ch[x][1]) Travel(ch[x][1]);
}
void debug(){
printf("root:%d\n",root);
Travel(root);
}
inline void Rotate(int x,int f) {
int y = pre[x];
pushdown(y);
pushdown(x);
ch[y][!f] = ch[x][f];
pre[ ch[x][f] ] = y;
pre[x] = pre[y];
if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] = x;
ch[x][f] = y;
pre[y] = x;
pushup(y);
}
inline void Splay(int x,int goal) {
pushdown(x);
while(pre[x] != goal) {
if(pre[pre[x]] == goal) {
Rotate(x , ch[pre[x]][0] == x);
} else {
int y = pre[x] , z = pre[y];
pushdown(z);
pushdown(y);
pushdown(x);
int f = (ch[z][0] == y);
if(ch[y][f] == x) {
Rotate(x , !f) , Rotate(x , f);
} else {
Rotate(y , f) , Rotate(x , f);
}
}
}
pushup(x);
if(goal == 0) root = x;
}
void Rotateto(int k,int goal) {
int x = root;
pushdown(x);
while(sz[ ch[x][0] ] != k) {
if(k < sz[ ch[x][0] ]) {
x = ch[x][0];
} else {
k -= (sz[ ch[x][0] ] + 1);
x = ch[x][1];
}
pushdown(x);
}
Splay(x,goal);
}
int Newnode(int x){
ch[x][0] = ch[x][1] = 0;
pre[x] = lazy[x] = 0;
sz[x] = 1;
val[x] = x;
return x;
}
inline void build(int &x,int l,int r,int f){
if(l > r) return;
int mid = (l + r) >> 1;
x = Newnode(mid);
build(ch[x][0],l,mid - 1,x);
build(ch[x][1],mid + 1,r,x);
pre[x] = f;
pushup(x);
}
inline void init(){
ch[0][0] = ch[0][1] = pre[0] = 0;
sz[0] = lazy[0] = val[0] = 0;
root = top = cnt = 0;
root = Newnode(n + 1);
ch[root][1] = Newnode(n + 2);
pre[ ch[root][1] ] = root;
sz[root] = 2;
build(keytree,1,n,ch[root][1]);
pushup(ch[root][1]);
pushup(root);
}
inline void flip(){
int l,r;
scanf("%d%d",&l,&r);
Rotateto(l - 1,0);
//debug();
Rotateto(r + 1,root);
lazy[keytree] ^= 1;
change(keytree);
}
inline void cut(){
int l,r,next;
scanf("%d%d%d",&l,&r,&next);
Rotateto(l - 1,0);
Rotateto(r + 1,root);
cnt = 0;
int tmp = keytree;
ch[ ch[root][1] ][0] = 0;
pushup(ch[root][1]);
Rotateto(next,0);
Rotateto(next + 1,root);
keytree = tmp;
pre[tmp] = ch[root][1];
pushup(ch[root][1]);
}
void output(int x){
pushdown(x);
if(ch[x][0]) output(ch[x][0]);
if(val[x] <= n){
cnt++;
printf("%d",val[x]);
printf(cnt == n?"\n":" ");
}
if(ch[x][1]) output(ch[x][1]);
}
int lazy[SIZEN];
int val[SIZEN];
};
SplayTree spt;
void solve(int n,int m){
char op[10];
spt.n = n;
spt.init();
while(m--){
scanf("%s",op);
if(op[0] == 'C') spt.cut();
else if(op[0] == 'F') spt.flip();
spt.cnt = 0;
}
spt.output(spt.root);
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(n < 0 && m < 0) break;
solve(n,m);
}
}