线段树【递归版本】

一个功能较为全面的线段树:

包括区间更新,区间查询最值(大/小),区间求和

有完整注释以及一道板子题

HDU-1166

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=5*1e4+7;
  4 int seq[maxn];  // must use index from 1
  5 
  6 struct Node{
  7     int l,r,maxx,minn;
  8     long long sum,lazy;
  9     // lazy for delaying child updating
 10     void update(int x){
 11         // update node storage value
 12         lazy+=x;
 13         sum+=1LL*(l-r+1)*x; // transfrom int to long long
 14         maxx+=x;
 15         minn+=x;
 16     }
 17     void __str__(){
 18         printf("l:%d r:%d maxx:%d minn:%d sum:%lld lazy:%lld
", 
 19                 l,r,maxx,minn,sum,lazy);
 20     }
 21 }Tree[maxn<<2]; // need 4 times space 
 22 
 23 void push_up(int id){
 24     // collect child node information
 25     Tree[id].sum=Tree[id<<1].sum+Tree[id<<1|1].sum;
 26     Tree[id].maxx=max(Tree[id<<1].maxx,Tree[id<<1|1].maxx);
 27     Tree[id].minn=min(Tree[id<<1].minn,Tree[id<<1|1].minn);
 28 }
 29 
 30 void push_down(int id){
 31     // only push down lazy to child, not update itselef
 32     // change itself value by push_up operation
 33     // if node has lazy value , push down lazy to child
 34     long long lazyval=Tree[id].lazy;
 35     if(lazyval){
 36         // cleaer lazy
 37         Tree[id].lazy=0; 
 38         // update child node, itself not change
 39         Tree[id<<1].update(lazyval);
 40         Tree[id<<1|1].update(lazyval);
 41     }
 42 }
 43 
 44 void build(int id,int l,int r){
 45     Tree[id].l=l;Tree[id].r=r;Tree[id].lazy=0;
 46     if(l==r){
 47         // leaf node
 48         Tree[id].sum=Tree[id].maxx=Tree[id].minn=seq[l];
 49     }else{
 50         // minddle node 
 51         int mid=l+((r-l)>>1);
 52         build(id<<1,l,mid);
 53         build(id<<1|1,mid+1,r);
 54         // update parent value
 55         push_up(id);
 56     }
 57 }
 58 
 59 void update(int id, int ql,int qr, int val){
 60     int L=Tree[id].l, R=Tree[id].r;
 61     if(ql<=L && R<=qr){
 62         // if query range contains range of now node, only to update it, 
 63         // don't update child, even to update leaf node.
 64         // only in this way to promise update operation by O(logn) 
 65         Tree[id].update(val);
 66     }else{
 67         push_down(id);
 68         int mid=L+((R-L)>>1);
 69         if(ql<=mid) update(id<<1,ql,qr,val);
 70         if(mid<qr) update(id<<1|1,ql,qr,val);
 71         push_up(id);
 72     }
 73 }
 74 
 75 long long querySum(int id,int ql,int qr){
 76     int L=Tree[id].l, R=Tree[id].r;
 77     if(ql<=L && R<=qr){
 78         // query range contains now node range, it dedicate that we can get result on the node
 79         return Tree[id].sum;
 80     }else{
 81         push_down(id);
 82         long long ans=0;
 83         int mid=L+((R-L)>>1);
 84         if(ql<=mid) ans+=querySum(id<<1,ql,qr);
 85         if(mid<qr) ans+=querySum(id<<1|1,ql,qr);
 86         push_up(id);
 87         return ans;
 88     }
 89 }
 90 
 91 int queryMax(int id, int ql, int qr){
 92     int L=Tree[id].l, R=Tree[id].r;
 93     if(ql<=L && R<=qr){
 94         return Tree[id].maxx;
 95     }else{
 96         push_down(id);
 97         int ans=-INF;
 98         int mid=L+((R-L)>>1);
 99         if(ql<=mid) ans=max(ans,queryMax(id<<1,ql,qr));
100         if(mid<qr) ans=max(ans,queryMax(id<<1|1,ql,qr));
101         push_up(id);
102         return ans;
103     }
104 }
105 
106 int queryMin(int id, int ql, int qr){
107     int L=Tree[id].l, R=Tree[id].r;
108     if(ql<=L && R<=qr){
109         return Tree[id].minn;
110     }else{
111         push_down(id);
112         int ans=INF;
113         int mid=L+((R-L)>>1);
114         if(ql<=mid) ans=min(ans,queryMin(id<<1,ql,qr));
115         if(mid<qr) ans=min(ans,queryMin(id<<1|1,ql,qr));
116         push_up(id);
117         return ans;
118     }
119 }
120 
121 int seqGet(int idx){
122     // get value in seq by index
123     return queryMax(1,idx,idx);
124 }
125 
126 int n;
127 int main(int argc, char const *argv[])
128 {
129     // https://vjudge.net/problem/HDU-1166
130     int T,kase=1;
131     char flag[10];
132     scanf("%d",&T);
133     while(T--){
134         scanf("%d",&n);
135         for(int i=1;i<=n;i++)
136             scanf("%d",&seq[i]);
137         build(1,1,n);
138         // print_tree();
139         printf("Case %d:
",kase++);
140         int i,j;
141         while(scanf("%s",flag) && flag[0]!='E'){
142             scanf("%d %d",&i,&j);
143             if(flag[0]=='A') update(1,i,i,j);
144             else if(flag[0]=='S') update(1,i,i,-j);
145             else printf("%lld
",querySum(1,i,j));
146         }
147     }
148     return 0;
149 }
原文地址:https://www.cnblogs.com/TianyuSu/p/10859937.html