线段树第一题,自己把模板一点点慢慢码出来。
线段树讲解:http://www.cnblogs.com/TenosDoIt/p/3453089.html
有一些注意点,比如要开4倍的MAXN,否则在数据较大时会RE,引用来自CSDN上的一段话:
1 #include<cstdio> 2 #define MAXN 100000+5 3 typedef long long ll; 4 struct Node{ 5 int l,r; 6 ll sum,lazy; 7 void update(ll x) 8 { 9 sum+=(r-l+1)*x; 10 lazy+=x; 11 } 12 }node[4*MAXN]; 13 int n,m,a[MAXN]; 14 void pushdown(int root) 15 { 16 if(node[root].lazy) 17 { 18 node[root*2].update(node[root].lazy); 19 node[root*2+1].update(node[root].lazy); 20 node[root].lazy=0; 21 } 22 } 23 void pushup(int root) 24 { 25 node[root].sum=node[root*2].sum+node[root*2+1].sum; 26 } 27 void build(int root,int l,int r) 28 { 29 node[root].l=l; node[root].r=r; 30 node[root].sum=0; node[root].lazy=0; 31 if(l==r) node[root].sum=a[l]; 32 else 33 { 34 int mid=l+(r-l)/2; 35 build(root*2,l,mid); 36 build(root*2+1,mid+1,r); 37 pushup(root); 38 } 39 } 40 void update(int root,int st,int ed,int val) 41 { 42 if(st>node[root].r || ed<node[root].l) return; 43 if(st<=node[root].l && node[root].r<=ed) node[root].update(val); 44 else 45 { 46 pushdown(root); 47 update(root*2,st,ed,val); 48 update(root*2+1,st,ed,val); 49 pushup(root); 50 } 51 } 52 ll query(int root,int st,int ed) 53 { 54 if(ed<node[root].l || node[root].r<st) return 0; 55 if(st<=node[root].l && node[root].r<=ed) return node[root].sum; 56 else 57 { 58 ll ans=0; 59 pushdown(root); 60 ans+=query(root*2,st,ed); 61 ans+=query(root*2+1,st,ed); 62 pushup(root); 63 return ans; 64 } 65 } 66 int main() 67 { 68 scanf("%d",&n); 69 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 70 build(1,1,n); 71 scanf("%d",&m); 72 for(int i=1;i<=m;i++) 73 { 74 int l,r,v; 75 scanf("%d%d%d",&l,&r,&v); 76 update(1,l,r,v); 77 printf("%lld\n",query(1,l,r)); 78 } 79 }
时间: 2024-11-06 22:05:27