码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3487 Play with Chain 【Splay】

时间:2016-07-22 21:03:47      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:

1-n的序列,有两种操作:

1,将一段区间翻转

2,将一段区间切下来放到剩余序列的第C个数后

采用延迟更新的方法维护区间的翻转,并维护一个size域。

添加一个最大点和一个最小点,防止出界

翻转时,将第L-1个点伸展到跟,再将第R+1个点伸展到L-1的右子树,这时R+1的左子树就是要翻转的区间,加上一个标记。

切区间时,跟翻转操作差不多,只是不加标记。然后找到C+1和C,将C伸展到根,C+1伸展到C的右子树,此时C+1的左子树就是要插入的位置。

其实我说了这么多并没有什么卵用。。。。最后还是得自己画图看才能懂。

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int N=3e5+111;
int data[N],num[N],t[N][2],id,fa[N];
int flip[N],root,f;
inline void pushup(int x){
    num[x]=num[t[x][0]]+num[t[x][1]]+1;
}
inline void pushdown(int x){
    if(flip[x]){
        flip[x]=0;
        flip[t[x][0]]^=1;
        flip[t[x][1]]^=1;
        swap(t[x][0],t[x][1]);
    }
}
inline void Rotate(int x,int w){
    int y=fa[x];
    int z=fa[y];
    pushdown(y);
    t[y][!w]=t[x][w];
    fa[t[x][w]]=y;
    t[z][t[z][1]==y]=x;
    fa[x]=z;
    t[x][w]=y;
    fa[y]=x;
    pushup(y);
}
void newnode(int &x,int y,int v){
    x=++id;
    t[x][0]=t[x][1]=0;
    fa[x]=y;
    data[x]=v,flip[x]=0;
    num[x]=1;
}
void build(int &x,int y,int l,int r){
    if(l<=r){
        int mid=(l+r)>>1;
        newnode(x,y,mid);
        build(t[x][0],x,l,mid-1);
        build(t[x][1],x,mid+1,r);
        pushup(x);
    }
}
void init(int n){
    f=id=root=0;
    t[0][0]=t[0][1]=num[0]=data[0]=flip[0]=fa[0]=0;
    newnode(root,0,-1);
    newnode(t[1][1],root,-1);
    build(t[t[1][1]][0],t[1][1],1,n);
    pushup(t[1][1]);
    pushup(1);
}
void Splay(int x,int y){
    if(x!=y){
        pushdown(x);
        while(fa[x]!=y){
            if(t[fa[x]][0]==x)
                Rotate(x,1);
            else
                Rotate(x,0);
        }
        pushup(x);
        if(!y)root=x;
    }
}
int Kth(int k){
    int x=root;
    pushdown(root);
    for(;num[t[x][0]]+1!=k;){
        if(num[t[x][0]]+1>k)
            x=t[x][0];
        else
            k-=num[t[x][0]]+1,x=t[x][1];
        pushdown(x);
    }
    return x;
}
void Flip(int a,int b){
    a=Kth(a);
    b=Kth(b+2);
    Splay(a,0);
    Splay(b,a);
    flip[t[b][0]]^=1;
}
void Cut(int a,int b,int c){
    int tmp,d;
    
    a=Kth(a);b=Kth(b+2);
    Splay(a,0);Splay(b,a);
    tmp=t[b][0];t[b][0]=0;
    pushup(b);pushup(a);
    
    d=Kth(c+2);c=Kth(c+1);
    Splay(c,0);Splay(d,c);
    t[d][0]=tmp;fa[tmp]=d;
    pushup(d);pushup(c);
}
void Inorder(int x){
    if(x){
        pushdown(x);
        Inorder(t[x][0]);
        if(data[x]>0){
            if(f)
                putchar( );
            else    f=1;
            printf("%d",data[x]);
        }
        Inorder(t[x][1]);
    }
}
int main(){
    int n,m;
    char op[9];
    while(scanf("%d%d",&n,&m)!=EOF){
        if(n==-1)break;
        init(n);
        int a,b,c;
        while(m--){
            scanf("%s",op);
            if(op[0]==F){
                scanf("%d%d",&a,&b);
                Flip(a,b);
            }else{
                scanf("%d%d%d",&a,&b,&c);
                Cut(a,b,c);
            }
        }
        Inorder(root);
        puts("");
    }
    return 0;
}

 

HDU 3487 Play with Chain 【Splay】

标签:

原文地址:http://www.cnblogs.com/L-King/p/5696907.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!