【模板】区间翻转平衡树

emm,也是借大佬的板子来学习平衡树的。

原文:https://blog.csdn.net/a_comme_amour/article/details/79382104

测板子:https://www.lydsy.com/JudgeOnline/problem.php?id=3223

在洛谷也测了一遍,但是感觉点好少,于是上bzoj上再测测。。。,洛谷:https://www.luogu.org/problem/P3391

 1  #include<bits/stdc++.h>
 2  using namespace std;
 3  const int N=1e5+8;
 4  const int inf=0x3f3f3f3f;
 5  int rt,sz;
 6  int a[N],f[N],ch[N][2],val[N],siz[N],tag[N];
 7  
 8  bool get(int x){ return ch[f[x]][1]==x;}
 9  void update(int x){siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;}
10  void pushdown(int x){
11      if( x && tag[x] ){
12          tag[ch[x][1]]^=1;
13          tag[ch[x][0]]^=1;
14          swap(ch[x][1],ch[x][0]);
15          tag[x]=0;
16      }
17  }
18  void rotate(int x){
19      int fa=f[x],ffa=f[fa],which=get(x);
20      pushdown(fa); pushdown(x);
21      ch[fa][which]=ch[x][which^1];f[ch[fa][which]]=fa;
22      ch[x][which^1]=fa;f[fa]=x;
23      f[x]=ffa;
24      if(ffa) ch[ffa][ch[ffa][1]==fa]=x;
25      update(fa); update(x);
26  }
27  void splay(int x,int goal){
28      for(int fa; (fa=f[x])!=goal ;rotate(x) ){
29          if(f[fa]!=goal) rotate( (get(x)==get(fa)) ? fa : x );
30     }
31     if(!goal) rt=x;
32  }
33  int build(int fa,int l,int r){
34      if(l>r) return 0;
35      int mid=(l+r)>>1;
36      int now=++sz;
37      val[now]=a[mid]; f[now]=fa; tag[now]=0;
38      ch[now][0]=build(now,l,mid-1);
39      ch[now][1]=build(now,mid+1,r);
40      update(now);
41      return now;
42  }
43  int find(int x){
44      int now=rt;
45      while(1){
46          pushdown(now);
47          if(x<=siz[ch[now][0]]) now=ch[now][0];
48          else{
49              x-=siz[ch[now][0]]+1;
50              if(!x) return now;
51              now=ch[now][1];
52          }
53      }
54  }
55  void turn(int l,int r){
56      l=find(l);
57      r=find(r+2);
58      splay(l,0);
59      splay(r,l);
60      pushdown(rt);
61      tag[ch[ch[rt][1]][0]]^=1;
62  }
63  void write(int x){
64      pushdown(x);
65      if(ch[x][0]) write(ch[x][0]);
66      if(val[x]!=inf && val[x]!=-inf) printf("%d ",val[x]);
67      if(ch[x][1]) write(ch[x][1]);
68  }
69  int main(){
70      int n,m;scanf("%d %d",&n,&m);
71      for(int i=2;i<=n+1;++i) a[i]=i-1;
72      a[1]=-inf;a[n+2]=inf;
73      rt=build(0,1,n+2);
74      for(int i=1;i<=m;++i){
75          int x,y;scanf("%d %d",&x,&y);
76          turn(x,y);
77      }
78      write(rt);
79      return 0;
80  }
View Code

猜你喜欢

转载自www.cnblogs.com/xiaobuxie/p/11309612.html