bzoj3223

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3700  Solved: 2097
[Submit][Status][Discuss]

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

抄了抄模板,自己yy不出来

区间操作

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100010
int n,m,root;
int size[N],fa[N],tag[N];
int child[N][2];
void update(int x)
{
    size[x]=size[child[x][0]]+size[child[x][1]]+1;
}
void zig(int x)
{
    int y=fa[x];
    fa[x]=fa[y];
    child[fa[x]][y==child[fa[x]][1]]=x;
    fa[child[x][1]]=y; child[y][0]=child[x][1];
    fa[y]=x; child[x][1]=y; 
    update(x); update(y);    
}
void zag(int x)
{
    int y=fa[x];
//    printf("----------------\n");
//    printf("fa[x]=%d\n",fa[x]);
    fa[x]=fa[y]; child[fa[x]][y==child[fa[x]][1]]=x;
//    printf("x=%d\n",x);
//    printf("fa[x]=%d\n",fa[x]);
//    printf("----------------\n");
    fa[child[x][0]]=y; child[y][1]=child[x][0];
    fa[y]=x; child[x][0]=y;
    update(x); update(y);
}
void splay(int x,int t)
{
    int a=fa[t];
    while(fa[x]!=a)
    {
        int y=fa[x],z=fa[y];
        if(y==t)
        {
            child[t][0]==x?zig(x):zag(x);
            break;
        }
        x==child[y][0]?zig(x):zag(x);
        x==child[z][0]?zig(x):zag(x);
        update(x);
    }
    if(!fa[x]) root=x;
    update(root);
}
void pushdown(int x)
{
    if(tag[x])
    {
        swap(child[x][0],child[x][1]);
        tag[child[x][0]]^=1;
        tag[child[x][1]]^=1;
        tag[x]^=1;
    }
}
int find(int x,int rank)
{
    pushdown(x);
//    printf("x=%d rank=%d\n",x,rank);
    if(size[child[x][0]]+1==rank) return x;
    else if(size[child[x][0]]>=rank) return find(child[x][0],rank);
    else return find(child[x][1],rank-size[child[x][0]]-1);
}
void turn(int a,int b)
{
    int x=find(root,a-1),y=find(root,b+1);
    splay(x,root); splay(y,child[root][1]);
    tag[child[child[root][1]][0]]^=1;
}
int main()
{
    scanf("%d%d",&n,&m);
    root=1;
    update(1);
    for(int i=2;i<=n+2;i++)
    {
        fa[i]=i-1;
        child[i-1][1]=i;
        update(i);
    }
    while(m--)
    {
        int a,b; scanf("%d%d",&a,&b);
        a++; b++;
        turn(a,b);
    }
//    printf("YES\n");
//    printf("root=%d\n",root);
    for(int i=2;i<=n+1;i++)
    {
//        printf("\n----------------\n");
        printf("%d ",find(root,i)-1);
    }
    return 0;
}
View Code

 

posted @ 2016-12-21 00:03  19992147  阅读(218)  评论(0编辑  收藏  举报