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;
    }
  • 相关阅读:
    创建线程的方式三:实现Callable接口 --- JDK 5.0新增
    线程的通信
    多线程的实例练习:银行账户双储户问题
    解决线程安全问题的方式三:Lock锁 --- JDK5.0新增
    演示线程的死锁问题
    Synchronized的各场景使用方法(多窗口售票例子接上篇)
    线程的【生命周期】和【线程的同步】(下面有多窗口售票例子)
    多线程:继承方式和实现方式的联系与区别
    创建多线程的方式二:实现Runnable接口
    Java项目生成可执行jar包、exe文件以及在Windows下的安装文件
  • 原文地址:https://www.cnblogs.com/Acheing/p/6786462.html
Copyright © 2011-2022 走看看