poj 3468 A Simple Problem with Integers (线段树 成段更新 加值 求和)
题意:
只有这两种操作
C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
代码风格更新后:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <algorithm> 7 #define lson l, mid, 2*rt 8 #define rson mid+1, r, 2*rt+1 9 #define LL __int64 10 const int maxn = 100000+10; 11 using namespace std; 12 LL sum[4*maxn], lz[4*maxn]; 13 14 void pushup(int rt) 15 { 16 sum[rt] = sum[2*rt]+sum[2*rt+1]; 17 } 18 void pushdown(int l, int r, int rt) 19 { 20 if(lz[rt]!=0) 21 { 22 int mid = (l+r)/2; 23 sum[2*rt] += lz[rt]*(mid-l+1); 24 sum[2*rt+1] += lz[rt]*(r-mid); 25 lz[2*rt] += lz[rt]; 26 lz[2*rt+1] += lz[rt]; 27 lz[rt] = 0; 28 } 29 } 30 void build(int l, int r, int rt) 31 { 32 if(l==r) 33 { 34 scanf("%I64d", &sum[rt]); 35 return; 36 } 37 int mid = (l+r)/2; 38 build(lson); 39 build(rson); 40 pushup(rt); 41 } 42 void update(int ll, int rr, LL c, int l, int r, int rt) 43 { 44 if(ll>r) return; 45 if(rr<l) return; 46 if(ll<=l && rr>=r) 47 { 48 lz[rt] += c; 49 sum[rt] += (r-l+1)*c; 50 return; 51 } 52 pushdown(l, r, rt); 53 int mid = (l+r)/2; 54 update(ll, rr, c, lson); 55 update(ll, rr, c, rson); 56 pushup(rt); 57 } 58 LL query(int ll, int rr, int l, int r, int rt) 59 { 60 if(ll>r) return 0; 61 if(rr<l) return 0; 62 if(ll<=l && rr>=r) 63 return sum[rt]; 64 pushdown(l, r, rt); 65 int mid = (l+r)/2; 66 return query(ll, rr, lson)+query(ll, rr, rson); 67 } 68 int main() 69 { 70 int n, q, a, b; 71 LL c; 72 char ch; 73 while(~scanf("%d%d", &n, &q)) 74 { 75 memset(sum, 0, sizeof(sum)); 76 memset(lz, 0, sizeof(lz)); 77 build(1, n, 1); 78 while(q--) 79 { 80 getchar(); 81 scanf("%c %d %d", &ch, &a, &b); 82 if(ch=='Q') 83 printf("%I64d\n", query(a, b, 1, n, 1)); 84 else 85 { 86 scanf("%I64d", &c); 87 update(a, b, c, 1, n, 1); 88 } 89 } 90 } 91 return 0; 92 }
代码风格更新前:
分析:自己写的有点麻烦了,写的时候手残+脑残,改了好久。
val+lazy*(r-l+1)表示和,如果lazy==0表示当前区间加的值不统一。
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 #define LL __int64 8 const int maxn = 100000+10; 9 using namespace std; 10 int n, q; 11 __int64 a[maxn]; 12 struct line 13 { 14 int l, r; 15 LL val, lazy; 16 }tr[4*maxn]; 17 18 void build(int o, int l, int r) 19 { 20 tr[o].l = l; tr[o].r = r; 21 tr[o].lazy = 0; 22 if(l==r) 23 { 24 tr[o].val = a[l]; 25 return; 26 } 27 int mid = (l+r)/2; 28 build(2*o, l, mid); 29 build(2*o+1, mid+1, r); 30 tr[o].val = tr[2*o].val+tr[2*o+1].val; 31 } 32 void update(int o, int l, int r, int add) 33 { 34 if(tr[o].l==l && tr[o].r==r) 35 { 36 tr[o].lazy += add; 37 return; 38 } 39 if(tr[o].lazy) //之前没向下更新的向下更新 40 { 41 tr[2*o].lazy += tr[o].lazy; 42 tr[2*o+1].lazy += tr[o].lazy; 43 tr[o].val += (LL)(tr[o].lazy*(tr[o].r-tr[o].l+1)); //同时把lazy存的加到和里 44 tr[o].lazy = 0; 45 } 46 tr[o].val += (LL)(add*(r-l+1)); //在这个过程中把新增加的加上,注意左右区间 47 int mid = (tr[o].l+tr[o].r)/2; 48 if(r <= mid) update(2*o, l, r, add); 49 else if(l > mid) update(2*o+1, l, r, add); 50 else 51 { 52 update(2*o, l, mid, add); 53 update(2*o+1, mid+1, r, add); 54 } 55 } 56 57 LL query(int o, int l, int r) 58 { 59 if(tr[o].l==l && tr[o].r==r) 60 return tr[o].val + tr[o].lazy*(r-l+1); 61 if(tr[o].lazy) //由于之前可能存在 没有更新的所以向下更新 62 { 63 tr[2*o].lazy += tr[o].lazy; 64 tr[2*o+1].lazy += tr[o].lazy; 65 tr[o].val += (LL)(tr[o].lazy*(tr[o].r-tr[o].l+1)); 66 tr[o].lazy = 0; 67 } 68 int mid = (tr[o].l+tr[o].r)/2; 69 if(r<=mid) return query(2*o, l, r); 70 else if(l > mid) return query(2*o+1, l, r); 71 else 72 { 73 return query(2*o, l, mid) + query(2*o+1, mid+1, r); 74 } 75 } 76 int main() 77 { 78 int i, l, r, add; 79 char ch; 80 while(~scanf("%d%d", &n, &q)) 81 { 82 for(i = 1; i <= n; i++) 83 scanf("%I64d", &a[i]); 84 build(1, 1, n); 85 for(i = 1; i <= q; i++) 86 { 87 getchar(); 88 scanf("%c", &ch); 89 if(ch=='Q') 90 { 91 scanf("%d%d", &l, &r); 92 printf("%I64d\n", query(1, l, r)); 93 } 94 else 95 { 96 scanf("%d%d%d", &l, &r, &add); 97 update(1, l, r, add); 98 } 99 } 100 } 101 return 0; 102 }