bzoj 3223: Tyvj 1729 文艺平衡树 (splay)

链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3223

题面:

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 7451  Solved: 4657
[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

 
实现代码:
#include<bits/stdc++.h>
using namespace std;
const int M = 2e5+10;
const int inf = 0x3f3f3f;
int n,m,sz,rt;
int c[M][2],fa[M],v[M],siz[M];
bool rev[M];

inline void up(int k){
    int l = c[k][0],r = c[k][1];
    siz[k] = siz[l] + siz[r] + 1;
}

void pushdown(int k){
    int l = c[k][0],r = c[k][1];
    if(rev[k]){
        rev[k] = 0; rev[l]^=1; rev[r]^=1;
        swap(c[k][0],c[k][1]);
    }
}

void rotate(int x,int &k){
    int y = fa[x],z = fa[y],l,r;
    if(c[y][0] == x) l = 0;
    else l = 1;
    r = l^1;
    if(y == k) k = x;
    else {
        if(c[z][0]==y) c[z][0]=x;
        else c[z][1] = x;
    }
    fa[x] = z;fa[y] = x;fa[c[x][r]]=y;
    c[y][l]=c[x][r]; c[x][r]=y;
    up(y); up(x);
}

void splay(int x,int &k){
    while(x != k){
        int y = fa[x],z = fa[y];
        if(y != k){
            if(c[y][0]==x^c[z][0]==y)rotate(x,k);
            else rotate(y,k);
        }
        rotate(x,k);
    }
}


int find(int k,int rk){
    if(rev[k]) pushdown(k);
    int l = c[k][0],r = c[k][1];
    if(siz[l] + 1 == rk) return k;
    else if(siz[l] >= rk) return find(l,rk);
    else return find(r,rk-siz[l]-1);
}

inline void reve(int l,int r){
    int x = find(rt,l),y = find(rt,r+2);
    splay(x,rt); splay(y,c[x][1]);
    int z = c[y][0];
    rev[z] ^= 1;
}

inline void build(int l,int r,int f)
{
    if(l>r)return;
    int now=l,last=f;
    if(l==r)
    {
        v[now]=l;siz[now]=1;fa[now]=last;
        if(l<f)c[last][0]=now;
        else c[last][1]=now;
        return;
    }
    int mid=(l+r)>>1;now=mid;
    build(l,mid-1,mid);build(mid+1,r,mid);
    v[now]=mid;fa[now]=last;
    if(mid<f)c[last][0]=now;
    else c[last][1]=now;
    up(now);
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int x,y;
    cin>>n>>m;
    build(1,n+2,0); rt = (n+3) >> 1;
    for(int i = 1;i <= m;i ++){
        cin>>x>>y;
        reve(x,y);
    }
    for(int i = 1;i <= n;i ++){
        cout<<find(rt,i+1)-1<<" ";
    }
    cout<<endl;
}

 

 

posted @ 2019-04-17 20:08  冥想选手  阅读(130)  评论(0编辑  收藏  举报