bzoj3223 文艺平衡树

来源:互联网 发布:德国世家知乎 编辑:程序博客网 时间:2024/05/17 01:22

传送门 :http://www.lydsy.com/JudgeOnline/problem.php?id=3223
splay区间翻转的基础题,然而我还是调了一晚上(蒟蒻的悲哀)

#include <cstdio>#include <cmath>#include <iostream>#include <cstring>#include <algorithm>using namespace std;int n,m,root,x,y;int ls[100005],rs[100005],s[100005],v[100005],lazy[100005],fa[100005],f[100005];void pushup(int rt){    s[rt]=s[ls[rt]]+s[rs[rt]]+1;}void pushdown(int rt){    if (!lazy[rt]) return;    swap(ls[rt],rs[rt]);    lazy[ls[rt]]^=1;    lazy[rs[rt]]^=1;    lazy[rt]=0;}void build(int l,int r,int fa){    if (l>r) return;    int now=v[l];    int last=v[fa];    if (l==r)    {        s[now]=1;        f[now]=last;        if (l<fa) ls[last]=now;        else rs[last]=now;        return;    }    int mid=(l+r)>>1;    now=v[mid];    build(l,mid-1,mid);    build(mid+1,r,mid);    f[now]=last;    if (mid<fa)  ls[last]=now;    else rs[last]=now;          pushup(mid);}void zig(int x){    int y=f[x],z=f[y];    if (ls[z]==y) ls[z]=x;    else rs[z]=x;    f[x]=z;    f[y]=x;    ls[y]=rs[x];    f[rs[x]]=y;    rs[x]=y;    pushup(y);    pushup(x);    if (y==root) root=x;}void zag(int x){    int y=f[x],z=f[y];    if (ls[z]==y) ls[z]=x;    else rs[z]=x;    f[x]=z;    f[y]=x;    rs[y]=ls[x];    f[ls[x]]=y;    ls[x]=y;    pushup(y);    pushup(x);    if (y==root) root=x;}void splay(int x,int k){    while(f[x]!=k)    {        if (ls[f[x]]==x) zig(x);        else zag(x);    }}int find(int &k,int x){    pushdown(k);    if(s[ls[k]]+1==x)return k;    if(s[ls[k]]>=x)return find(ls[k],x);    return find(rs[k],x-s[ls[k]]-1);}void lazye(int l,int r){    int x=find(root,l);    int y=find(root,r);    splay(x,0);    splay(y,x);    lazy[ls[y]]^=1;}int main(){    scanf("%d%d",&n,&m);    for (int i=1;i<=n+2;i++)    {        v[i]=i;    }    root=(n+3)>>1;    build(1,n+2,0);    for (int i=1;i<=m;i++)    {        scanf("%d%d",&x,&y);        lazye(x,y+2);    }    for (int i=2;i<=n+1;i++)    {        printf("%d ",find(root,i)-1);    }}
0 0