Description
Input
Output
Sample Input
1 10 1 2 3 4 5 6 7 8 9 10 Query 1 3 Add 3 6 Query 2 7 Sub 10 2 Add 6 3 Query 3 10 End
Sample Output
Case 1: 6 33 59
题目大意:中文题目,不解释。
解题思路:与之前那题大致相同,只是之前那题要求最高分,而这题要求总和。
#include<stdio.h>
#include<string.h>
#define N 50005 * 4
int S[N], L[N], R[N], V[N];
void build(int n, int l, int r) { //建线段树
if (l == r) {
R[n] = L[n] = l;
S[n] = V[l];
}else {
int mid = (l + r) / 2;
L[n * 2] = l;
R[n * 2] = mid;
L[n * 2 + 1] = mid + 1;
R[n * 2 + 1] = r;
build(n * 2 , L[n * 2], R[n * 2]);
build(n * 2 + 1, L[n * 2 + 1], R[n * 2 + 1]);
S[n] = S[n * 2] + S[n * 2 + 1]; //改成求和
}
}
void modify(int n, int x, int v) { //修改数据
if (L[n] == x && R[n] == x) {
S[n] += v;
return;
}
int mid = (L[n] + R[n]) / 2;
if (x <= mid) {
modify(n * 2, x, v);
}
else {
modify(n * 2 + 1, x, v);
}
S[n] = S[n * 2] + S[n * 2 + 1]; //维护线段树
}
int find(int n, int l, int r) { //输出区间和
if (l <= L[n] && r >= R[n]) {
return S[n];
}
int mid = (L[n] + R[n]) / 2;
int sum = 0;
if (l <= mid) {
sum += find(n * 2, l, r);
}
if (r > mid) {
sum += find(n * 2 + 1, l, r);
}
return sum;
}
int main() {
int cnt, cnt2 = 1;
while (scanf("%d\n", &cnt) == 1) {
while (cnt--) {
memset(S, 0, sizeof(S));
memset(L, 0, sizeof(L));
memset(R, 0, sizeof(R));
memset(V, 0, sizeof(V));
int cnt3 = 0, n;
printf("Case %d:\n", cnt2++);
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &V[i]);
}
L[1] = 1;
R[1] = n;
build(1, 1, n);
char O[100];
int a, b;
memset(O, 0, sizeof(O));
while (scanf("%s", O)) {
if (O[0] == 'A') {
scanf("%d %d", &a, &b);
modify(1, a, b);
}
else if (O[0] == 'S') {
scanf("%d %d", &a, &b);
modify(1, a, -b);
}
else if (O[0] == 'Q') {
scanf("%d %d", &a, &b);
printf("%d\n", find(1, a, b));
}
else {
break;
}
}
}
}
return 0;
}
原文:http://blog.csdn.net/llx523113241/article/details/42221561