文艺平衡树(区间翻转)

哇,只会fhq treap的我瑟瑟发抖,不能旋转,那怎么区间翻转啊。

QAQ

仔细一想(看了博客)发现十分简单,也还是暴力拆,只不过用tag标记,交换子树就好了还是很简单的吗

至于不会fhq treap的同学可以先点这里或上 Patrickpwq大佬的博客

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<ctime>
  7 using namespace std;
  8 const int maxn=100010;
  9 int n,m,val[maxn],rnd[maxn],son[maxn][3],size[maxn],sum_p;
 10 int tag[maxn],root=0;
 11 inline void read(int &x)
 12 {
 13     x=0; 
 14     int f=1; 
 15     char ch=getchar();
 16     while(ch<'0'||ch>'9')
 17     {
 18         if(ch=='-') 
 19         f=-1; 
 20         ch=getchar();
 21     }
 22     while(ch>='0'&&ch<='9')
 23     {
 24         x=x*10+ch-'0';
 25         ch=getchar();
 26     }
 27     x*=f;
 28 }
 29 inline void update(int x)
 30 {
 31     size[x]=size[son[x][1]]+size[son[x][2]]+1;   
 32     if(x&&tag[x])
 33     {
 34         tag[x]^=1;
 35         swap(son[x][1],son[x][2]);
 36         tag[son[x][1]]^=1,tag[son[x][2]]^=1;
 37     }
 38 }
 39 inline int newnode(int x)
 40 {
 41     ++sum_p;size[sum_p]=1;
 42     val[sum_p]=x;rnd[sum_p]=rand();
 43     tag[sum_p]=0;
 44     return sum_p; 
 45 }
 46 int merge(int x,int y)
 47 {
 48     if(x==0||y==0) return x+y;
 49     update(x),update(y);
 50     if(rnd[x]<rnd[y]) 
 51     {
 52         son[x][2]=merge(son[x][2],y);
 53         update(x);
 54         return x;
 55     }
 56     else
 57     {
 58         son[y][1]=merge(x,son[y][1]);
 59         update(y);
 60         return y;
 61     }
 62 }
 63 inline void split(int &x,int &y,int k,int pos)
 64 {
 65     if(!pos)
 66     x=y=0;
 67     else
 68     {
 69         update(pos);
 70         if(k<=size[son[pos][1]])
 71         {
 72             y=pos;
 73             split(x,son[pos][1],k,son[pos][1]);
 74         }
 75         else
 76         {
 77             x=pos;
 78             split(son[pos][2],y,k-size[son[pos][1]]-1,son[pos][2]);
 79         }
 80         update(pos);
 81     }
 82 }
 83 void rev(int l,int r)
 84 {
 85     int a,b,c,d;
 86     split(a,b,r+1,root);
 87     split(c,d,l,a);
 88     tag[d]=1;
 89     root=merge(merge(c,d),b);
 90 }
 91 void print(int x)
 92 {
 93     if(!x) return;
 94     update(x);
 95     print(son[x][1]);
 96     if (val[x]>=1&&val[x]<=n) printf("%d ",val[x]);
 97     print(son[x][2]);
 98 }
 99 int main()
100 {
101     srand((unsigned)time(NULL));
102     scanf("%d%d",&n,&m);
103     root=build(1,n+2);
104     for(register int i=1;i<=m;i++)
105     {
106         register int l,r;
107         scanf("%d%d",&l,&r);
108         rev(l,r);
109     }
110     print(root);
111 }

 

posted @ 2018-08-23 20:33  __mashiro  阅读(188)  评论(0编辑  收藏  举报