zoukankan      html  css  js  c++  java
  • bzoj 3223: Tyvj 1729 文艺平衡树

    Description

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

    Input

    第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
    接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n

    Output

    输出一行n个数字,表示原始序列经过m次变换后的结果

    Sample Input

    5 3 

    1 3

    1 3

    1 4

    Sample Output

    4 3 2 1 5

    HINT N,M<=100000

    题解:

    splay模板题,调了半天。。。

    代码

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    struct node{int f,l,r,rev,size;}tree[100010];
    int i,j,k,n,m,x,y,t,rt,num,id[100010];
    void pushup(int k){tree[k].size=tree[tree[k].l].size+tree[tree[k].r].size+1;}
    void build(){
        tree[1].f=-1;tree[1].size=n+2;
        for (i=2;i<=n;i++){tree[i-1].r=i;tree[i].f=i-1;tree[i].size=n-i+1;}
    }
    void pushdown(int rt){
        if (tree[rt].rev){
            tree[rt].rev=0;swap(tree[rt].l,tree[rt].r);
            tree[tree[rt].l].rev^=1;tree[tree[rt].r].rev^=1;
        }
    }
    void rotate(int x,int &k){
        int y=tree[x].f,z=tree[y].f,l=0;
        if (tree[y].l==x)l=1;else l=0;
        if(y==k)k=x;
        else {if(tree[z].l==y)tree[z].l=x;else tree[z].r=x;}
        tree[x].f=z;tree[y].f=x;
        if (l==1){tree[tree[x].r].f=y;tree[y].l=tree[x].r;tree[x].r=y;}
        else {tree[tree[x].l].f=y;tree[y].r=tree[x].l;tree[x].l=y;}
        pushup(y);pushup(x);
    }
    void splay(int x,int &goal){
        while (x!=goal){
            int y=tree[x].f,z=tree[y].f;
            if (y==goal){rotate(x,goal);break;}
            if ((tree[z].l==y)^(tree[y].l==x))rotate(x,goal);else rotate(y,goal);
            rotate(x,goal);
        }
    }
    int find(int x,int rt){
        pushdown(rt);
        //printf("%d %d
    ",x,rt);
        if (tree[tree[rt].l].size+1==x)return rt;
        if (tree[tree[rt].l].size+1>x)return find(x,tree[rt].l);
        else return find(x-tree[tree[rt].l].size-1,tree[rt].r);
    }
    void print(int rt){
        if (rt==0)return;
        int now=rt;
        printf("%d %d %d %d
    ",rt,tree[now].l,tree[now].r,tree[now].size);
        print(tree[now].l);print(tree[now].r);
    }
    int main(){
        scanf("%d%d",&n,&m);n+=2;
        build();rt=1;
        //print(rt);
        for (i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            x=find(x,rt);
            y=find(y+2,rt);
            //printf("%d %d
    ",x,y);
            splay(y,rt);splay(x,tree[rt].l);
            tree[tree[tree[rt].l].r].rev^=1;
            //for (k=2;k<=n-1;k++)printf("%d ",find(k,rt)-1);printf("
    ");
        }
        for (i=2;i<=n-1;i++)printf("%d ",find(i,rt)-1);
        return 0;
    }
  • 相关阅读:
    PAT 甲级 1132 Cut Integer (20 分)
    AcWing 7.混合背包问题
    AcWing 9. 分组背包问题
    AcWing 5. 多重背包问题 II
    AcWing 3. 完全背包问题
    AcWing 4. 多重背包问题
    AcWing 2. 01背包问题
    AcWing 875. 快速幂
    AcWing 874. 筛法求欧拉函数
    AcWing 873. 欧拉函数
  • 原文地址:https://www.cnblogs.com/Acheing/p/6786462.html
Copyright © 2011-2022 走看看