題目鏈接:http://acm.nyist.net/JudgeOnline/problem.php?pid=116
根據題意可知該題與士兵殺敵(一)不同,可以用樹狀數組來解這題,先來解釋一下樹狀數組
如圖:
可以得到:
1
2
3
|
int lowbit( int x){ return x&(x^(x–1)); } |
1
2
3
|
int lowbit( int x){ return x&-x; } |
修改操作
1
2
3
4
5
6
7
8
|
void add( int k, int num) { while (k<=n) { tree[k]+=num; k+=k&-k; } } |
查詢操作
1
2
3
4
5
6
7
8
9
10
|
int read( int k) //1~k的區間和 { int sum=0; while (k) { sum+=tree[k]; k-=k&-k; } return sum; } |
#include<stdio.h>
int N, M, T[1000001];
//求k中有多少個能被2的多少次冪整除的,即2^k,也就是樹狀數組的作用域
int lowbit(int k) {
return k & (k ^ (k - 1)); //利用機器補碼特性也可以這樣寫 k & (-k);
}
void add(int k, int num) { //添加新值到樹狀數組中
while(k <= N) {
T[k] += num;
k += lowbit(k);
}
}
int sum(int k) { //前k個數的和
int sum = 0;
while(k) {
sum += T[k];
k -= lowbit(k);
}
return sum;
}
int main() {
int a, m, n, I, A;
char str[5];
scanf("%d%d", &N, &M);
for(int i = 1; i <= N; i++) {
scanf("%d", &a);
add(i, a);
}
while(M--) {
scanf("%s", str);
if(str[0] == 'Q') {
scanf("%d%d", &m, &n);
printf("%d\n", sum(n) - sum(m-1));
}
else {
scanf("%d%d", &I, &A);
add(I, A);
}
}
}