59
基本的思想,就是还是将一个线段继续分割,一直分割到不能分割,这道题目是知道多少个军营,也就是区间为1-n, 将它分割, 建立树, 可以不用保存它区间的左端点和右端点,用数组下标代表就可以了, 数组的值代表当前军营里人的个数,然后这个题就是单个点的增加或者减少,其实增加减少都是增加,减少只是把增加的数目变成负数就行了,还有就是更新完最下面的点还要一直往上更新。下面是代码实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.Arrays;
public class Main {
static int[] A = new int[1000005];
static int[] Sum = new int[1000000];
static void BuildLineTree(int node, int start, int end) {
if (start == end) {
Sum[node] = A[start];
return;
}
int mid = (start + end) >> 1;
BuildLineTree(node << 1, start, mid);
BuildLineTree(node << 1 | 1, mid + 1, end);
UpdateSum(node);
}
static void UpdateSum(int node) {
Sum[node] = Sum[node << 1] + Sum[node << 1 | 1];
}
static void Add(int i, int j, int node, int start, int end) {
if (start == end) {
Sum[node] += j;
return;
}
int mid = (start + end) >> 1;
if (i <= mid) {
Add(i, j, node << 1, start, mid);
} else {
Add(i, j, node << 1 | 1, mid + 1, end);
}
UpdateSum(node);
}
static int Query(int L, int R, int start, int end, int node) {
if (L <= start && end <= R) {
return Sum[node];
}
int sum = 0;
int mid = (start + end) >> 1;
if (L <= mid) {
sum += Query(L, R, start, mid, node << 1);
}
if (R > mid) {
sum += Query(L, R, mid + 1, end, node << 1 | 1);
}
return sum;
}
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(bf.readLine());
int N = 0;
int i, j;
String[] commends;
String commend = "";
for (int k = 1; k <= T; k++) {
N = Integer.parseInt(bf.readLine());
String number = bf.readLine();
String[] numbers = number.split("\\s");
for (int num = 1; num <= N; num++) {
A[num] = Integer.parseInt(numbers[num - 1]);
}
BuildLineTree(1, 1, N);
System.out.println("Case " + k + ":");
while (true) {
commend = bf.readLine();
commends = commend.split("\\s");
if (commend.startsWith("Query")) {
i = Integer.parseInt(commends[1]);
j = Integer.parseInt(commends[2]);
System.out.println(Query(i, j, 1, N, 1));
} else if (commend.startsWith("Add")) {
i = Integer.parseInt(commends[1]);
j = Integer.parseInt(commends[2]);
Add(i, j, 1, 1, N);
} else if (commend.startsWith("Sub")) {
i = Integer.parseInt(commends[1]);
j = Integer.parseInt(commends[2]);
Add(i, -j, 1, 1, N);
}
else if (commend.startsWith("End")) {
break;
}
}
}
}
}