线段树-sum/max/min/区间更新

写一个板子。

  1 #include <cstdio>
  2 #include <algorithm>
  3 
  4 using namespace std;
  5 
  6 const int maxn = 100000+10;
  7 
  8 #define ROOT     1, 1, N
  9 #define lson(x)  (x<<1)
 10 #define rson(x)  (x<<1|1)
 11 
 12 struct SegmentTree{
 13     int l, r;
 14     int ma, mi, sum;
 15     int lazy;
 16     int lazy_ma, lazy_mi;
 17 }st[maxn << 2];
 18 
 19 int val[maxn],N;
 20 
 21 void push_up(int x){
 22     st[x].sum = st[lson(x)].sum + st[rson(x)].sum;
 23     st[x].ma  = max(st[lson(x)].ma, st[rson(x)].ma);
 24     st[x].mi  = min(st[lson(x)].mi, st[rson(x)].mi);
 25 }
 26 
 27 void push_down(int x, int m){
 28     if(st[x].lazy){
 29         st[lson(x)].sum += (m-(m>>1)) * st[x].lazy;
 30         st[rson(x)].sum += (m>>1) * st[x].lazy;
 31         st[lson(x)].ma += st[x].lazy; st[lson(x)].mi += st[x].lazy;
 32         st[rson(x)].ma += st[x].lazy; st[rson(x)].mi += st[x].lazy;
 33         
 34         st[lson(x)].lazy += st[x].lazy;
 35         st[rson(x)].lazy += st[x].lazy;
 36 
 37         st[x].lazy = 0;
 38     }
 39 }
 40 
 41 void build(int x, int l, int r){
 42     st[x].l = l;st[x].r = r;
 43     st[x].lazy = st[x].lazy_mi = st[x].lazy_ma = 0;
 44 
 45     if(l == r){
 46         st[x].sum = val[l];
 47         st[x].ma = st[x].mi = val[l];
 48         return ;
 49     }
 50     int mid = (l+r)>>1;
 51     build(lson(x), l, mid);
 52     build(rson(x), mid+1, r);
 53     push_up(x);
 54 }
 55 
 56 void update(int L, int R, int c, int x,int l,int r){
 57     if(L <= l && R >= r){
 58         st[x].sum += c * (r-l+1);
 59         st[x].ma += c;
 60         st[x].mi += c;
 61         st[x].lazy += c; 
 62         return ;
 63     }
 64     push_down(x, r-l+1);
 65     
 66     int mid = (l+r)>>1;
 67     if(L <= mid) update(L, R, c, lson(x), l, mid);
 68     if(R > mid) update(L, R, c, rson(x), mid+1, r);
 69     push_up(x);
 70 }
 71 
 72 int query_sum(int L, int R, int x, int l, int r){
 73     if(L <= l && R >= r){
 74         return st[x].sum;
 75     }
 76     push_down(x, r-l+1);
 77 
 78     int mid = (l+r)>>1, res = 0;
 79     if(R <= mid)      res = query_sum(L, R, lson(x), l, mid);
 80     else if(L > mid) res = query_sum(L, R, rson(x), mid+1, r);
 81     else          res = query_sum(L, R, lson(x), l, mid) + query_sum(L, R, rson(x), mid+1, r);
 82     push_up(x);
 83     return res;
 84 }
 85 
 86 int query_max(int L,int R, int x, int l, int r){
 87     if(L <= l && R >= r){
 88         return st[x].ma;
 89     }
 90     push_down(x, r-l+1);
 91 
 92     int mid = (l+r)>>1, res = 0;
 93     if(R <= mid)      res = query_max(L, R, lson(x), l, mid);
 94     else if(L > mid) res = query_max(L, R, rson(x), mid+1, r);
 95     else              res = max(query_max(L, R, lson(x), l, mid), query_max(L, R, rson(x), mid+1, r));
 96     push_up(x);
 97     return res;    
 98 }
 99 
100 int query_min(int L,int R, int x, int l, int r){
101     if(L <= l && R >= r){
102         return st[x].mi;
103     }
104     push_down(x, r-l+1);
105 
106     int mid = (l+r)>>1, res = 0;
107     if(R <= mid)      res = query_min(L, R, lson(x), l, mid);
108     else if(L > mid) res = query_min(L, R, rson(x), mid+1, r);
109     else              res = min(query_min(L, R, lson(x), l, mid), query_min(L, R, rson(x), mid+1, r));
110     push_up(x);
111     return res;    
112 }
113 
114 int T,M;
115 
116 int main(){
117     scanf("%d", &T);
118     while(T--){
119         scanf("%d %d\n", &N, &M);
120         for(int i=1;i<=N;i++) scanf("%d", &val[i]);
121         build(ROOT);
122 
123         for(int i=0;i<M;i++){
124             char op[10];
125             int l, r, c;
126             scanf("%s", op);
127             if(op[0] == 'Q' && op[1] == 'S'){
128                 scanf("%d %d", &l, &r);
129                 printf("%d\n", query_sum(l, r, ROOT));
130             }else if(op[0] == 'Q' && op[1] == 'A'){
131                 scanf("%d %d", &l, &r);
132                 printf("%d\n", query_max(l, r, ROOT));
133             }else if(op[0] == 'Q' && op[1] == 'I'){
134                 scanf("%d %d", &l, &r);
135                 printf("%d\n", query_min(l, r, ROOT));
136             }else if(op[0] == 'I'){
137                 scanf("%d %d %d", &l, &r, &c);
138                 update(l, r, c, ROOT);
139             }
140         }
141     }
142 }

 

posted @ 2018-03-31 18:22  Helica  阅读(430)  评论(0编辑  收藏  举报