UVA 11922 Permutation Transformer(Splay【伸展樹】的一些操作)

題目鏈接:https://cn.vjudge.net/problem/UVA-11922

Write a program to transform the permutation 1, 2, 3, … , n according to m instructions. Each instruction
(a, b) means to take out the subsequence from the a-th to the b-th element, reverse it, then append
it to the end.
Input
There is only one case for this problem. The first line contains two integers n and m (1 ≤ n, m ≤
100, 000). Each of the next m lines contains an instruction consisting of two integers a and b (1 ≤ a ≤
b ≤ n).
Output
Print n lines, one for each integer, the final permutation.
Explanation of the sample below
Instruction (2,5): Take out the subsequence {2,3,4,5}, reverse it to {5,4,3,2}, append it to the
remaining permutation {1,6,7,8,9,10}
Instruction (4,8): The subsequence from the 4-th to the 8-th element of {1,6,7,8,9,10,5,4,3,2} is
{8,9,10,5,4}. Take it out, reverse it, and you’ll get the sample output.
Sample Input
10 2
2 5
4 8
Sample Output
1
6
7
3
2
4
5
10
9
8
【中文題意&&思路分析】
稍後補上
【AC代碼】

#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
using namespace std;

struct Node
{
    Node *ch[2];
    int s,v,flip;
    int cmp(int k)
    {
        int d=k-ch[0]->s;
        if(d==1)return -1;
        return d <=0?0:1;
    }
    void maintain()
    {
        s=ch[0]->s+ch[1]->s+1;
    }
    void pushdown()
    {
        if(flip)
        {
            flip=0;
            swap(ch[0],ch[1]);
            ch[0]->flip=!(ch[0]->flip);
            ch[1]->flip=!(ch[1]->flip);
        }
    }
};

Node *null=new Node();
void rotate(Node* &o,int d)
{
    Node *k=o->ch[d^1];
    o->ch[d^1]=k->ch[d];
    k->ch[d]=o;
    o->maintain();
    k->maintain();
    o=k;
}

void splay(Node* &o,int k)
{
    o->pushdown();
    int d=o->cmp(k);
    if(d==1)k-=o->ch[0]->s+1;
    if(d!=-1)
    {
        Node *p=o->ch[d];
        p->pushdown();
        int d2=p->cmp(k);
        int k2=(d2 == 0 ? k : k -1- p->ch[0]->s);
        if(d2!=-1)
        {
            splay(p->ch[d2],k2);
            if(d==d2)
            {
                rotate(o,d^1);
            }
            else
            {
                rotate(o->ch[d],d);
            }
        }
        rotate(o,d^1);
    }
}

Node* merge(Node* left,Node* right)
{
    splay(left,left->s);
    left->ch[1]=right;
    left->maintain();
    return left;
}

void split(Node* o,int k,Node* &left,Node* &right)
{
    splay(o,k);
    left=o;
    right=o->ch[1];
    o->ch[1]=null;
    left->maintain();
}

const int maxn=100000+10;
struct SplaySequence
{
    int n;
    Node seq[maxn];
    Node *root;
    Node* build(int sz)
    {
        if(sz==0)return null;
        Node* L=build(sz/2);
        Node* o=&seq[++n];
        o->v=n;
        o->ch[0]=L;
        o->ch[1]=build(sz-sz/2-1);
        o->s=o->flip=0;
        o->maintain();
        return o;
    }
    void init(int sz)
    {
        n=0;
        null->s=0;
        root=build(sz);
    }
};

vector<int>ans;

void print(Node* o)
{
    if(o!=null)
    {
        o->pushdown();
        print(o->ch[0]);
        ans.push_back(o->v);
        print(o->ch[1]);
    }
}

void debug(Node* o)
{
    if(o!=null)
    {
        o->pushdown();
        debug(o->ch[0]);
        printf("%d ",o->v-1);
        debug(o->ch[1]);
    }
}

SplaySequence ss;

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    ss.init(n+1);

    while(m--)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        Node *o,*mid,*left,*right;
        split(ss.root,a,left,o);
        split(o,b-a+1,mid,right);
        mid->flip^=1;
        ss.root=merge(merge(left,right),mid);
    }
    print(ss.root);
    for(int i=1;i<ans.size();i++)
    {
        printf("%d\n",ans[i]-1);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章