树状数组模板题 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
",ans);
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/virtual-north-Illya/p/10045147.html