TYVJ2195 序列终结者

三种操作

1.区间加上某个数  增加add域表示加值懒惰标记

2.区间翻转  增加rev域表示翻转懒惰标记

3.返回区间最值  增加mx域表示以当前节点为根节点的子树的最大值

更新的 时候一定要先把当前节点更新,再加懒惰标记。

pushup的时候最好是判断下左右节点是否存在(这个题是必须判断),这是一个很良好的习惯

  1 #include <cstdio>
  2 #include <algorithm>
  3 using namespace std;
  4 const int maxn = 59993;
  5 int fa[maxn],son[2][maxn],mx[maxn],add[maxn],lz[maxn],val[maxn],siz[maxn];
  6 int root,tot;
  7 void pushup(int x){
  8     int l = son[0][x],r = son[1][x];
  9     mx[x] = val[x];
 10     if(l)mx[x] = max(mx[x],mx[l]);
 11     if(r)mx[x] = max(mx[x],mx[r]);
 12     siz[x] = siz[l]+siz[r]+1;
 13 }
 14 void pushdown(int x){
 15     int l = son[0][x],r = son[1][x];
 16     if(add[x]){
 17         val[l]+=add[x];val[r]+=add[x];
 18         mx[l]+=add[x];mx[r]+=add[x];
 19         add[l]+=add[x];add[r]+=add[x];
 20         add[x] = 0;
 21     }
 22     if(lz[x]){
 23         swap(son[0][l],son[1][l]);
 24         swap(son[0][r],son[1][r]);
 25         lz[r]^=1;lz[l]^=1;
 26         lz[x] = 0;
 27     }
 28 }
 29 void rota(int w,int x){
 30     int y = fa[x];
 31     son[!w][y] = son[w][x];
 32     if(son[w][x])fa[son[w][x]] = y;
 33     fa[x] = fa[y];
 34     if(fa[y])son[y==son[1][fa[y]]][fa[y]] = x;
 35     fa[y] = x;
 36     son[w][x] = y;
 37     pushup(y);pushup(x);
 38 }
 39 void splay(int x,int y){
 40     while(fa[x]!=y){
 41         if(fa[fa[x]]==y)rota(x==son[0][fa[x]],x);
 42         else {
 43             int w = fa[x]==son[0][fa[fa[x]]];
 44             if(x==son[w][fa[x]]){
 45                 rota(!w,x);rota(w,x);
 46             }
 47             else {
 48                 rota(w,fa[x]);rota(w,x);
 49             }
 50         }
 51     }
 52     if(y==0)root = x;
 53 }
 54 int getk(int k){
 55     int x = root;
 56     while(1){
 57         pushdown(x);
 58         if(k==siz[son[0][x]]+1)return x;
 59         if(k<=siz[son[0][x]])x = son[0][x];
 60         else {
 61             k-=(siz[son[0][x]]+1);
 62             x = son[1][x];
 63         }
 64     }
 65 }
 66 int query(int l,int r){
 67     int x = getk(l-1),y = getk(r+1);
 68     splay(x,0);splay(y,x);
 69     return mx[son[0][y]];
 70 }
 71 void rev(int l,int r){
 72     int x = getk(l-1),y = getk(r+1);
 73     splay(x,0);splay(y,x);
 74     int z = son[0][y];
 75     swap(son[0][z],son[1][z]);
 76     lz[z]^=1;
 77 }
 78 void update(int l,int r,int v){
 79     int x = getk(l-1),y = getk(r+1);
 80     splay(x,0);splay(y,x);
 81     val[son[0][y]]+=v;
 82     mx[son[0][y]]+=v;
 83     add[son[0][y]]+=v;
 84 }
 85 int main()
 86 {
 87     int n,m;scanf("%d%d",&n,&m);
 88     for(int i = 1;i<=n+2;++i){
 89         if(i==1){
 90             root = ++tot;
 91             siz[root] = 1;
 92             continue;
 93         }
 94         son[0][++tot] = root;
 95         fa[root] = tot;
 96         siz[tot] = siz[root]+1;
 97         root = tot;
 98     }
 99     while(m--){
100         int op,l,r,v;scanf("%d%d%d",&op,&l,&r);
101         if(op==1){
102             scanf("%d",&v);
103             update(l+1,r+1,v);
104         }
105         else if(op==2)rev(l+1,r+1);
106         else printf("%d\n",query(l+1,r+1));
107     }
108     return 0;
109 }

 

posted on 2015-08-25 00:36  round_0  阅读(140)  评论(0编辑  收藏  举报

导航