BZOJ5063旅游——非旋转treap

题目描述

小奇成功打开了大科学家的电脑。
大科学家打算前往n处景点旅游,他用一个序列来维护它们之间的顺序。初
始时,序列为1,2,...,n。
接着,大科学家进行m次操作来打乱顺序。每次操作有6步:
1、从序列开头(左端)取出A个数(此时序列剩下n-A个数)
2、从序列开头取出B个数
3、将第1步取出的A个数按原顺序放回序列开头
4、从序列开头取出C个数
5、将第2步取出的B个数逆序放回序列开头
6、将第4步取出的C个数按原顺序放回序列开头
你需要求出最终序列。

输入

第一行两个数n,m。接下来m行,每行三个数A,B,C。
n,m<=100000

输出

输出一行n个数表示最终序列。

样例输入

10 2
6 2 2
5 3 6

样例输出

1 2 8 7 3 9 6 5 4 10
 
非旋转treap模板题,直接按题意操作就好了,输出时直接dfs一遍整棵treap,注意不要忘记下传旋转标记。
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int r[100010];
int ls[100010];
int rs[100010];
int size[100010];
int v[100010];
int s[100010];
int cnt;
int n,m;
int A,B,C;
int x,y,z;
int root;
inline int build(int x)
{
    int rt=++cnt;
    v[rt]=x;
    r[rt]=rand();
    size[rt]=1;
    return rt;
}
inline void pushup(int rt)
{
    size[rt]=size[ls[rt]]+size[rs[rt]]+1;
}
inline void pushdown(int rt)
{
    if(s[rt])
    {
        s[rt]^=1;
        s[ls[rt]]^=1;
        s[rs[rt]]^=1;
        swap(ls[rt],rs[rt]);
    }
}
inline void split(int rt,int &x,int &y,int k)
{
    if(!rt)
    {
        x=y=0;
        return ;
    }
    pushdown(rt);
    if(size[ls[rt]]>=k)
    {
        y=rt;
        split(ls[rt],x,ls[y],k);
        pushup(rt);
    }
    else
    {
        x=rt;
        split(rs[rt],rs[x],y,k-size[ls[rt]]-1);
        pushup(rt);
    }
}
inline int merge(int x,int y)
{
    if(!x||!y)
    {
        return x+y;
    }
    pushdown(x);
    pushdown(y);
    if(r[x]<r[y])
    {
        rs[x]=merge(rs[x],y);
        pushup(x);
        return x;
    }
    else
    {
        ls[y]=merge(x,ls[y]);
        pushup(y);
        return y;
    }
}
inline int build(int l,int r)
{
    if(l==r)
    {
        return build(l);
    }
    int mid=(l+r)>>1;
    return merge(build(l,mid),build(mid+1,r));
}
inline void print(int rt)
{
    pushdown(rt);
    if(ls[rt])
    {
        print(ls[rt]);
    }
    printf("%d ",v[rt]);
    if(rs[rt])
    {   
        print(rs[rt]);
    }
}
int main()
{
    srand(12378);
    scanf("%d%d",&n,&m);
    root=build(1,n);
    while(m--)
    {
        scanf("%d%d%d",&A,&B,&C);
        split(root,x,y,A);
        split(y,y,z,B);
        s[y]^=1;
        x=merge(x,z);
        split(x,x,z,C);
        root=merge(merge(x,y),z);
    }
    print(root);
}
原文地址:https://www.cnblogs.com/Khada-Jhin/p/10213872.html