题意:
给出一些值 然后给出你一些命令 按照命令输出
命令:
C a b c 表示更新a ~ b的值加上 c
Q a b 表示查询a~b的和
输入:
n m 表示有n个数 m 个操作
接下来 m 行为命令行
思路:
就是简单的线段树成段更新求和
Tips:
※ 询问的时候要 pushdown
※ 注意范围问题吖~
Code:
1 #include <stdio.h> 2 #include <cstring> 3 using namespace std; 4 #define LL long long 5 6 const int MAXN = 100010; 7 LL sum[MAXN<<2], lazy[MAXN<<2]; 8 9 void pushup(int rt) 10 { 11 sum[rt] = sum[rt<<1]+sum[rt<<1|1]; 12 } 13 14 void pushdown(int rt, int x) 15 { 16 if(lazy[rt] != 0) { 17 lazy[rt<<1] += lazy[rt]; 18 lazy[rt<<1|1] += lazy[rt]; 19 sum[rt<<1] += (LL)(x-(x>>1))*lazy[rt]; 20 sum[rt<<1|1] += (LL)(x>>1)*lazy[rt]; 21 lazy[rt] = 0; 22 } 23 } 24 25 void creat(int l, int r, int rt) 26 { 27 lazy[rt] = 0; 28 if(l == r) { 29 scanf("%lld", &sum[rt]); 30 return; 31 } 32 int mid = (l+r)>>1; 33 creat(l, mid, rt<<1); 34 creat(mid+1, r, rt<<1|1); 35 pushup(rt); 36 } 37 38 void modify(int l, int r, int x, int L, int R, int rt) 39 { 40 if(l <= L && r >= R) { 41 lazy[rt] += (LL)x; 42 sum[rt] += (LL)x*(R-L+1); 43 return; 44 } 45 pushdown(rt, R-L+1); 46 int mid = (L+R)>>1; 47 if(l <= mid) modify(l, r, x, L, mid, rt<<1); 48 if(r > mid) modify(l, r, x, mid+1, R, rt<<1|1); 49 pushup(rt); 50 } 51 52 LL query(int l, int r, int L, int R, int rt) 53 { 54 if(l <= L && r >= R) { 55 return (LL)sum[rt]; 56 } 57 pushdown(rt, R-L+1);///!!!! 58 int mid = (L+R)>>1; 59 LL ans = 0; 60 if(l <= mid) ans += query(l, r, L, mid, rt<<1); 61 if(r > mid) ans += query(l, r, mid+1, R, rt<<1|1); 62 return ans; 63 } 64 65 int main() 66 { 67 int i, j, k; 68 int n, m; 69 int a, b, c; 70 char opt[2]; 71 while(scanf("%d %d", &n, &m) != EOF) { 72 creat(1, n, 1); 73 while(m--) { 74 scanf("%s %d %d", opt, &a, &b); 75 if(opt[0] == 'Q') { 76 printf("%lld\n", query(a, b, 1, n, 1)); 77 } else if (opt[0] == 'C') { 78 scanf("%d", &c); 79 modify(a, b, c, 1, n, 1); 80 } 81 } 82 } 83 return 0; 84 }