Hdu 3487 play the chain

Description
瑶瑶很喜欢玩项链,她有一根项链上面有很多宝石,宝石从1到n编号。
首先,项链上的宝石的编号组成一个序列:1,2,3,...,n。
她喜欢两种操作:
1.CUT a b c:他会先将a至b号宝石切下来,然后接到c号宝石后面,组成一个新的项链。
举个例子,如果n=8,那么这个项链上的宝石编号依次为:1 2 3 4 5 6 7 8;'CUT 3 5 4',首先我们把3到5号宝石切下,项链变成了:1 2 6 7 8;然后接到4号宝石后面,此时的4号宝石为7,所以此时的项链变成了:1 2 6 7 3 4 5 8.
2.FLIP a b:像第一个操作一样我们先将a至b号宝石切下来,然后将其旋转180°,变成与原来相反的链,在插入到项链的相 同位置中。
举个例子,取操作1中的链:1 2 3 4 5 6 7 8,执行FLIP 2 6操作,则项链将变成:1 6 5 4 3 2 7 8.
他想知道经过m个操作之后项链会变成怎样。

Input
对于每一个数据,第一行会有两个整数:n m(1<=n,m<=300000) n代表宝石的个数,m代表操作的个数。
接下来有M行 有两个操作:
CUT A B C //代表CUT操作,1<=A<=B<=N, 0<=C<=N-(B-A+1).
FLIP A B //代表FLIP操作,1<=A<=B<=N.
输出的结尾将会有两个负数,他们不能当做操作.

Output
对于每一个数据,你需要输出N个整数,任两个数字间用一个空格分开,代表最终得到的项链的从1到N的宝石的序列号。

Sample Input
8 2
CUT 3 5 4
FLIP 2 6
-1 -1

Sample Output
1 4 3 7 6 2 5 8

多了区间操作的splay,为了防止越界,我们可以在最前面和最后面加上两个不动点,每次需要对区间[l,r]进行修改时,我们先把编号为l的点splay到根,再把编号为r+2的点splay到根,在旋的时候,l可能会变成r+2的孙子,我们把l单旋一下即可。这样子的话,l的左儿子就为我们需要求的那段区间了。

双旋的时候,2可能会变成5的孙子,那么我们把2单旋一下即可

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
    int x=0,f=1;char ch=getchar();
    for (;ch<'0'||ch>'9';ch=getchar())  if (ch=='-')    f=-1;
    for (;ch>='0'&&ch<='9';ch=getchar())    x=(x<<1)+(x<<3)+ch-'0';
    return x*f;
}
inline void print(int x){
    if (x>=10)     print(x/10);
    putchar(x%10+'0');
}
const int N=3e5;
int n,m;
struct Splay{
    #define T(x) (tree[f[x]][1]==x)
    int tree[N+10][2],f[N+10],size[N+10];
    bool flag[N+10];
    int root,cnt;
    void clear(){
        root=cnt=0;
        memset(f,0,sizeof(f));
        memset(tree,0,sizeof(tree));
        memset(size,0,sizeof(size));
        memset(flag,0,sizeof(flag));
    }
    void pushdown(int x){
        if (!flag[x])   return;
        swap(tree[x][0],tree[x][1]);
        flag[tree[x][0]]^=1;
        flag[tree[x][1]]^=1;
        flag[x]=0;
    }
    void write(int x){
        if (!x) return;
        pushdown(x);
        write(tree[x][0]);
        if (x<=n)   ++cnt!=n?printf("%d ",x):printf("%d\n",x);
        write(tree[x][1]);
    }
    void build(){
        root=n+1;
        for (int i=1;i<=n;i++)  f[i]=i+1,size[i]=i+1,tree[i+1][0]=i;
        f[n+2]=1,size[n+2]=1,tree[1][0]=n+2;
        size[root]=n+2;
    }
    void updata(int x){size[x]=size[tree[x][0]]+size[tree[x][1]]+1;}
    void move(int x){
        int fa=f[x],son=tree[x][T(x)^1];
        tree[x][T(x)^1]=fa;
        tree[fa][T(x)]=son;
        if (son)    f[son]=fa;
        f[x]=f[fa];
        if (f[x])   tree[f[x]][T(fa)]=x;
        f[fa]=x;
        updata(fa),updata(x);
    }
    void splay(int x){
        while (f[x]){
            if (f[f[x]])    T(x)==T(f[x])?move(f[x]):move(x);
            move(x);
        }
        root=x;
    }
    int find(int x,int i){
        if (!i) return 0;
        pushdown(i);
        if (size[tree[i][0]]+1==x)  return i;
        if (x<=size[tree[i][0]])    return find(x,tree[i][0]);
        return find(x-size[tree[i][0]]-1,tree[i][1]);
    }
    void flip(){//区间翻转,打个标记即可
        int x=read(),y=read();
        x=find(x,root),splay(x);
        y=find(y+2,root),splay(y);
        if (f[x]!=root) move(x);
        flag[tree[x][1]]^=1;
    }
    void consert(int x,int fa){//连边
        if (tree[f[x]][T(x)]==x)    tree[f[x]][T(x)]=0;
        f[tree[fa][0]=x]=fa;
    }
    void up(int x){while (f[x]) updata(x),x=f[x];}//向上更新
    void cut(){//区间切断
        int x=read(),y=read(),z=read();
        x=find(x+1,root),splay(x);
        y=find(y+2,root),splay(y);
        if (f[x]!=root) move(x);
        consert(tree[x][0],f[x]);
        z=find(z+2,root);
        consert(tree[z][0],x);
        consert(x,z);
        up(x);
    }
}T;
char s[10];
int main(){
    while (1){
        T.clear();
        n=read(),m=read();
        if (n==-1&&m==-1)   break;
        T.build();
        for (int i=1;i<=m;i++){
            scanf("%s",s);
            if (s[0]=='F')  T.flip();
            if (s[0]=='C')  T.cut();
        }
        T.write(T.root);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Wolfycz/p/9479739.html