地址 https://vjudge.ppsucxtt.cn/problem/POJ-3468
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations.
One type of operation is to add some given number to each number in a given interval.
The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"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.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
4
55
9
15
Hint
The sums may exceed the range of 32-bit integers.
解答 题目的大意是
给出一个整数数列, A[1] ~~ A[N]
有以下两个操作
1 Q a b 查询数组A[]中 索引a到索引b所有的数的和
2 C a b c 对数组A[]中 索引a到索引b的所有的数 全部加上一个数c
对于每个操作1的查询 打印出结果 结果占一行
对于线段树方案,这是一个区间更新 区间查询的方案。
对于区间更新,不能高效的实现对一段区域添加一个值,因为需要对这个区间相关的所有节点均进行更新
todo
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <assert.h>
#include <algorithm>
using namespace std;
const int N = 100010;
struct Node {
int l; int r;
long long sum;
long long add;
}t[4 * N];
int arr[N];
int n, m;
void build(int p, int l, int r) {
t[p].l = l; t[p].r = r;
if (l == r) { t[p].sum = arr[l]; return; }
int mid = (l + r) >> 1;
build(p * 2, l, mid);
build(p * 2 + 1, mid + 1, r);
t[p].sum = t[p * 2].sum + t[p * 2 + 1].sum;
}
void pushDown(int p) {
if (t[p].add) {
t[p * 2].sum += t[p].add*(t[p*2].r-t[p*2].l+1);
t[p * 2+1].sum += t[p].add*(t[p * 2+1].r - t[p * 2+1].l + 1);
t[p * 2].add += t[p].add;
t[p * 2+1].add += t[p].add;
t[p].add = 0;
}
}
void update(int p, int l, int r, int d) {
if (l <= t[p].l && r >= t[p].r) {
t[p].sum += (long long)d* (t[p].r - t[p].l + 1);
t[p].add += d;
return;
}
pushDown(p);
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid) update(p * 2, l, r, d);
if (r > mid) update(p * 2 + 1, l, r, d);
t[p].sum = t[p * 2].sum + t[p * 2 + 1].sum;
}
long long query(int p, int l, int r) {
if (l <= t[p].l && r >= t[p].r) return t[p].sum;
pushDown(p);
int mid = (t[p].l + t[p].r) >> 1;
long long val = 0;
if (l <= mid) val += query(p * 2, l, r);
if (r > mid) val += query(p * 2 + 1, l, r);
return val;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++) {
scanf("%d",&arr[i]);
}
build(1, 1, n);
for (int i = 0; i < m; i++) {
char Q[2];
int j, k, l;
scanf("%s", &Q);
if (Q[0] == 'Q') {
scanf("%d%d",&j,&k);
printf("%lld\n", query(1,j,k));
}
else if(Q[0]=='C') {
scanf("%d%d%d", &j, &k,&l);
update(1,j,k,l);
}
else {
assert(0);
}
}
return 0;
}