树状数组模板题 P1904
Description
给定一个长度为n的整数数组A[1]、A[2]、…、An,和m个操作:
操作1:1 i x 把A[i]的值增加x(-103<=A[i]<=103);
操作2:2 i j 查询当前序列的连续子序列A[i]..A[j]的和。
Input
第一行包含两个整数n和m,表示数组有n个元素,m表示有m个操作;接下来的一行包含n个整数,第i个整数表示A[i];再接下来的m行,每行表示一个操作。
Output
按输入顺序输出操作2的结果。
Hint
反正要用long long
Solution
嗯,这个题,告诉我们,位运算要打括号。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define maxn 100005
#define lowbit(x) (x&(-x))
using namespace std;
long long c[maxn];
long long n,m,z,u,z2,ans1,ans2,ans;
void doadd(long long x,long long y){
while(x<=n){
c[x]=c[x]+y;
x=x+lowbit(x);
}
}
long long sets(long long x){
long long s=0;
while(x>0){
s+=c[x];
x-=lowbit(x);
}
return s;
}
int main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&z);
doadd(i,z);
}
for(int j=1;j<=m;j++){
scanf("%lld",&u);
if(u==1){
scanf("%lld%lld",&z2,&z);
doadd(z2,z);
}
else{
scanf("%lld%lld",&z2,&z);
ans1=sets(z);
ans2=sets(z2-1);
ans=ans1-ans2;
printf("%lld\n",ans);
}
}
return 0;
}