BZOJ3223/洛谷P3391 - 文艺平衡树

BZOJ链接 洛谷链接

题意

模板题啦~×2

代码

//文艺平衡树
#include <cstdio>
#include <algorithm>
using namespace std;
int const N=1e5+10;
int n,m;
int rt,fa[N],ch[N][2],siz[N]; bool rev[N];
int wh(int p) {return p==ch[fa[p]][1];}
void update(int p) {siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;}
void pushdown(int p)
{
    if(rev[p])
    {
        swap(ch[p][0],ch[p][1]);
        rev[ch[p][0]]^=1; rev[ch[p][1]]^=1;
        rev[p]=false;
    }
}
void trPrint()
{
    for(int i=1;i<=n+2;i++) printf("%d fa=%d son=%2d,%2d siz=%d rev=%d\n",i,fa[i],ch[i][0],ch[i][1],siz[i],rev[i]);
    printf("\n");
}
void rotate(int p,int &k)
{
    int q=fa[p],r=fa[q],w=wh(p);
    if(q==k) k=p;
    else ch[r][q==ch[r][1]]=p;
    fa[ch[q][w]=ch[p][w^1]]=q;
    fa[ch[p][w^1]=q]=p; fa[p]=r;
    update(q); update(p);
    //printf("After rotate(%d)\n",p); trPrint();
}
void splay(int p,int &k)
{
    //printf("Splay %d to %d.\n",p,k);
    while(p!=k)
    {
        int q=fa[p],r=fa[q];
        if(q!=k)
            if(wh(p)^wh(q)) rotate(p,k);
            else rotate(q,k);
        rotate(p,k);
    }
}
int build(int fr,int to)
{
    if(fr>to) return 0;
    if(fr==to) {siz[fr]=1; return fr;}
    int p=(fr+to)>>1;
    fa[ch[p][0]=build(fr,p-1)]=p;
    fa[ch[p][1]=build(p+1,to)]=p;
    update(p);
    return p;
}
int find(int x)
{
    int p=rt;
    while(true)
    {
        pushdown(p);
        //printf("Find No.%d in %d.\n",x,p);
        int sizL=siz[ch[p][0]]+1;
        if(sizL>x) p=ch[p][0];
        if(sizL==x) return p;
        if(sizL<x) p=ch[p][1],x-=sizL;
    }
}
void reverse(int fr,int to)
{
    int p1=find(fr-1),p2=find(to+1);
    //printf("Reverse [%d,%d], p1=%d, p2=%d\n",fr,to,p1,p2);
    splay(p1,rt); splay(p2,ch[rt][1]);
    int p=ch[p2][0];
    rev[p]^=1;
    //trPrint();
}
void type(int p)
{
    if(p==0) return;
    pushdown(p);
    type(ch[p][0]);
    if(p!=1 && p!=n+2) printf("%d ",p-1);
    type(ch[p][1]);
}
int main()
{
    scanf("%d%d",&n,&m);
    rt=(n+3)>>1;
    build(1,n+2);
    for(int owo=1;owo<=m;owo++)
    {
        int fr,to;
        scanf("%d%d",&fr,&to);
        reverse(fr+1,to+1);
    }
    type(rt);
    return 0;
}
posted @ 2017-11-30 17:21  VisJiao  阅读(143)  评论(0编辑  收藏  举报