Uva11922 Splay

来源:互联网 发布:联合国comtrade数据库 编辑:程序博客网 时间:2024/06/11 05:01

题意:就是splay的区间翻转 然后直接加到序列的末尾

解法:大概是很轻松的 

#include<cstdio>#include<string.h>#include<iostream>using namespace std;#define maxn 222222#define ls ch[rt][0]#define rs ch[rt][1]#define rrs ch[root][1]#define rls ch[root][0]int val[maxn],num[maxn],ch[maxn][2],fa[maxn],root,cnt,rev[maxn];inline void up(int rt){num[rt]=num[ls]+num[rs]+1;}inline void down(int rt){    if(rev[rt]){        rev[ls]^=1;rev[rs]^=1;swap(ls,rs);rev[rt]=0;    }}inline void node(int rt){fa[rt]=val[rt]=ls=rs=0;num[rt]=1;rev[rt]=0;}inline void rot(int rt){    int f=fa[rt],side=ch[f][1]==rt,ll=ch[rt][!side];    fa[ll]=f,ch[f][side]=ll;    fa[rt]=fa[f],ch[fa[f]][ch[fa[f]][1]==f]=rt;    fa[f]=rt,ch[rt][!side]=f;    up(f),up(rt);}inline void splay(int rt,int aim){    while(fa[rt]!=aim){        down(rt);        int f=fa[rt],ff=fa[f];        if(ff==aim)rot(rt);        else if((ch[f][1]==rt)==(ch[ff][1]==f))rot(f),rot(rt);        else rot(rt),rot(rt);    }if(!aim)root=rt;}inline void find(int tot,int sub){    int rt=sub;    while(1){        down(rt);        if(num[ls]+1==tot)break;        if(num[ls]>=tot)rt=ls;        else tot-=num[ls]+1,rt=rs;    }splay(rt,fa[sub]);}inline void build(int n){    cnt=0;node(0);num[0]=0;    node(++cnt);    for(int i=2;i<=n+1;++i){        node(++cnt);fa[i-1]=i;ch[i][0]=i-1;val[i]=i-1;up(i);    }    node(++cnt);fa[cnt]=cnt-1;ch[cnt-1][1]=cnt;    root=cnt-1;up(root);}int ans[maxn],sz;void answer(int rt){    down(rt);    if(ls)answer(ls);    ans[sz++]=val[rt];    if(rs)answer(rs);}int main(){    int n,m,l,r;    while(~scanf("%d%d",&n,&m)){        build(n);        while(m--){            scanf("%d%d",&l,&r);            find(l,root);find(r-l+2,rrs);            int rt=ch[rrs][0];//            printf("%d %d\n",val[root],val[rrs]);            ch[rrs][0]=0;            rev[rt]^=1;up(rrs);up(root);n-=num[rt];            find(n+1,root);find(1,rrs);            fa[rt]=rrs,ch[rrs][0]=rt;            up(rrs),up(root),n+=num[rt];        }        sz=0;        answer(root);        for(int i=1;i<=n;++i)printf("%d\n",ans[i]);    }    return 0;}


0 0