3223: Tyvj 1729 文艺平衡树

来源:互联网 发布:三星手机 数据恢复 编辑:程序博客网 时间:2024/06/05 04:49

题目链接

题目大意:维护区间翻转

题解:fhq treap
丢板子跑

我的收获:

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>using namespace std;#define INF 0x7fffffffconst int M=100005;int n,m,tot,root;int c[M][2],sz[M],k[M],pri[M];bool rev[M];inline int node(int v){sz[++tot]=1,k[tot]=v,pri[tot]=rand();return tot;}inline void pushup(int x){sz[x]=sz[c[x][0]]+sz[c[x][1]]+1;} void pushdown(int x){    if(!rev[x]) return ;    int &l=c[x][0],&r=c[x][1];    rev[l]^=1;rev[r]^=1;swap(l,r);    rev[x]=0;}int merge(int x,int y){    if(!x||!y) return x+y;    pushdown(x),pushdown(y);    if(pri[x]<pri[y])    {        c[x][1]=merge(c[x][1],y);        pushup(x);        return x;    }    else    {           c[y][0]=merge(x,c[y][0]);        pushup(y);        return y;    }}void split(int now,int w,int &x,int &y){    if(!now) x=y=0;    else    {        pushdown(now);        if(w<sz[c[now][0]]+1)            y=now,split(c[now][0],w,x,c[now][0]);        else            x=now,split(c[now][1],w-(sz[c[now][0]]+1),c[now][1],y);        pushup(now);    }}int build(int l,int r){    if(l>r) return 0;    int m=l+r>>1,v=m-1;    int x=node(v);    c[x][0]=build(l,m-1);    c[x][1]=build(m+1,r);    pushup(x);    return x;}void dfs(int x){    if(!x) return ;    pushdown(x);    dfs(c[x][0]);    if(k[x]>=1&&k[x]<=n) printf("%d ",k[x]);    dfs(c[x][1]);}void rever(int l,int r){    int a,b,c,d;    split(root,r+1,a,b);    split(a,l,c,d);    rev[d]^=1;    root=merge(merge(c,d),b);}void work(){    int l,r;    while(m--) scanf("%d%d",&l,&r),rever(l,r);    dfs(root);    putchar('\n');}void init(){    scanf("%d%d",&n,&m);    root=build(1,n+2);} int main(){    srand(19260817^2151551);    init();    work();    return 0;}
原创粉丝点击