【题解】【HDU 3487】Play with Chain

  • Post author:
  • Post category:其他


简洁の题意:

有一个数列,有n个元素,从左到右依次为1,2,3…n。

有2种操作:

CUT a b c 把第a个元素到第b个元素取走,放在剩下的数列中的第c个元素后。

FILP a b 把区间a到b翻转。

给定m个操作,输出最后的数列。


百度了好久好像都是用splay做的啊QAQ

我根本不会打splay啊QAQ


于是我们果断放弃

我们不是还有FHQ_treap吗qwq

翻转操作见洛谷文艺平衡树

考虑CUT操作

首先,分离出x~y区间(都会的对吧)

然后合并1~x-1和y+1~n区间

分离1~c区间

插入x~y区间

合并

The end

调了30min的代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;

const int inf=2e9;
int root;

struct note
{
    int val;
    int size;
    int rd;
    int tag;
    int ch[2];
};

struct fhq_treap
{
    int cnt;
    note tree[100010];
    inline void up(int o)
    {
        tree[o].size=tree[tree[o].ch[0]].size+tree[tree[o].ch[1]].size+1;
    }
    inline void down(int o)
    {
        if(!tree[o].tag||!o)
        {
            return;
        }
        tree[o].ch[0]^=tree[o].ch[1]^=tree[o].ch[0]^=tree[o].ch[1];
        tree[tree[o].ch[0]].tag^=1;
        tree[tree[o].ch[1]].tag^=1;
        tree[o].tag=0;
    }
    void split(int x,int val,int &a,int &b)
    {
        if(!x)
        {
            a=b=0;
            return;
        }
        down(x);
        if(val>tree[tree[x].ch[0]].size)
        {
            a=x;
            split(tree[x].ch[1],val-tree[tree[x].ch[0]].size-1,tree[x].ch[1],b);
        }
        else
        {
            b=x;
            split(tree[x].ch[0],val,a,tree[x].ch[0]);
        }
        up(x);
    }
    int merge(int x,int y)
    {
        if((!x)||(!y))
        {
            return x+y;
        }
        down(x);
        down(y);
        if(tree[x].rd<tree[y].rd)
        {
            tree[x].ch[1]=merge(tree[x].ch[1],y);
            up(x);
            return x;
        }
        else
        {
            tree[y].ch[0]=merge(x,tree[y].ch[0]);
            up(y);
            return y;
        }
    }
    inline int new_node(int val)
    {
        tree[++cnt].val=val;
        tree[cnt].size=1;
        tree[cnt].rd=rand();
        return cnt;
    }
    inline void res(int x,int y)
    {
        int a,b,c,d;
        split(root,y,a,b);
        split(a,x-1,c,d);
        tree[d].tag^=1;
        root=merge(merge(c,d),b);
    }
    inline void cut(int x,int y,int pos)
    {
        int a,b,c,d;
        split(root,y,a,b);
        split(a,x-1,c,d);
        root=merge(c,b);
        int e,f;
        split(root,pos,e,f);
        root=merge(merge(e,d),f);
    }
    void print(int o)
    {
        if(!o)
        {
            return;
        }
        down(o);
        print(tree[o].ch[0]);
        printf("%d ",tree[o].val);
        print(tree[o].ch[1]);
    }
};

fhq_treap ft;
int n,m;

int main()
{
    srand((unsigned)time(0));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        root=ft.merge(root,ft.new_node(i));
    }
    for(int i=1;i<=m;i++)
    {
        string opx;
        cin>>opx;
        if(opx=="CUT")
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            ft.cut(x,y,z);
        }
        else
        {
            int x,y;
            scanf("%d%d",&x,&y);
            ft.res(x,y);
        }
    }
    ft.print(root);
    return 0;
}

转载于:https://www.cnblogs.com/tt66ea-blog/p/10275776.html