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\n",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\n",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\n",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("\n");
    }
    for (i=2;i<=n-1;i++)printf("%d ",find(i,rt)-1);
    return 0;
}

 

posted @ 2017-04-29 22:13  Acheing  阅读(173)  评论(0编辑  收藏  举报