小工是南将军手下的军师,南将军经常想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧。
南将军的某次询问之后士兵i可能又杀敌q人,之后南将军再询问的时候,需要考虑到新增的杀敌数。
输入
只有一组测试数据
第一行是两个整数N,M,其中N表示士兵的个数(1<N<1000000),M表示指令的条数。(1<M<100000)
随后的一行是N个整数,ai表示第i号士兵杀敌数目。(0<=ai<=100)
随后的M行每行是一条指令,这条指令包含了一个字符串和两个整数,首先是一个字符串,如果是字符串QUERY则表示南将军进行了查询操作,后面的两个整数m,n,表示查询的起始与终止士兵编号;如果是字符串ADD则后面跟的两个整数I,A(1<=I<=N,1<=A<=100),表示第I个士兵新增杀敌数为A.
输出
对于每次查询,输出一个整数R表示第m号士兵到第n号士兵的总杀敌数,每组输出占一行
样例输入
5 6
1 2 3 4 5
QUERY 1 3
ADD 1 2
QUERY 1 3
ADD 2 3
QUERY 1 2
QUERY 1 5
样例输出
6
8
8
20
代码如下:
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;
int num[1000010];
int res[1000010];
int N;
int lowbit(int n) //计算res数组中第n个位置掌管的元素个数
{
return n & (-n);
//return n&(n^(n-1)); //结果同上
}
void add(int i, int plus) //将第i个元素增加plus(更新)
{
while(i <= N)
{
res[i] += plus;
i += lowbit(i); //只更新与之关联的res数组元素
}
}
int sum(int n) //求前n项的和
{
int result = 0;
while(n > 0)
{
result += res[n];
n -= lowbit(n); //只加上范围最大的res数组元素
}
return result;
}
int main()
{
int M, i, key, num, plus, start, end;
char str[10];
scanf("%d%d", &N, &M);
for(i = 1; i <= N; ++i)
{
scanf("%d", &key);
add(i, key);
}
while(M--)
{
scanf("%s", str);
if(strcmp(str, "ADD") == 0)
{
scanf("%d%d", &num, &plus);
add(num, plus);
}
else
{
scanf("%d%d", &start, &end);
printf("%d\n", sum(end) - sum(start - 1));
}
}
/*while(M--) //简化后
{
char str[10];
int first, last;
scanf("%s%d%d", str, &first, &last);
if(strcmp(str, "ADD") == 0)
add(first, last);
else
printf("%d\n", sum(last) - sum(first - 1));
}*/
return 0;
}