poj3468(线段树-区间修改)

模板题:

#include<cstdio>#include<cstring>#define ll long longconst int N = 100000 + 10;ll sum[N << 2];ll addv[N << 2];int num[N];int n,q;void pushUp(int u) {sum[u] = sum[u * 2] + sum[u * 2 + 1];}void build(int u, int L, int R) {if(L == R) {sum[u] = num[L];return;}int mid = (L + R) / 2;build(u * 2, L, mid);build(u * 2 + 1, mid + 1, R);pushUp(u);}void pushDown(int u, int len) {int l = u * 2, r = u * 2 + 1;if(addv[u]) {addv[l] += addv[u];addv[r] += addv[u];sum[l] += (len – len / 2) * addv[u];sum[r] += (len / 2) * addv[u];addv[u] = 0;}};void update(int L, int R, int v, int u, int l, int r) {if(L <= l && R >= r) {sum[u] += (r – l + 1) * v;addv[u] += v;return;}pushDown(u, r – l + 1);int mid = (l + r) / 2;if(L <= mid)update(L, R, v, u * 2, l, mid);if(R > mid)update(L, R, v, u * 2 + 1, mid + 1, r);pushUp(u);}ll query(int L, int R, int u, int l, int r) {ll ans = 0;if(L <= l && R >= r) {return sum[u];}pushDown(u, r – l + 1);int mid = (l + r) / 2;if(L <= mid)ans += query(L, R, u * 2, l ,mid);if(R > mid) ans += query(L, R, u * 2 + 1, mid + 1, r);return ans;}int main() {while(scanf("%d%d",&n,&q) == 2) {memset(sum, 0 ,sizeof(sum));memset(addv, 0 ,sizeof(addv));for(int i = 1; i <= n; i++) {scanf("%d",&num[i]);}build(1, 1, n);for(int i = 0; i < q; i++) {getchar();char c = getchar();if(c == 'C') {int a,b,c;scanf("%d%d%d",&a,&b,&c);update(a, b, c, 1, 1, n);}if(c == 'Q') {int a,b;scanf("%d%d",&a,&b);printf("%lld\n",query(a, b, 1, 1, n));}}}return 0; }

,德有多高,艺有多深。

poj3468(线段树-区间修改)

相关文章:

你感兴趣的文章:

标签云: