P3374 【模板】树状数组 1


P3374 【模板】树状数组 1



时间限制 1.00s
内存限制 125.00MB


题目描述


如题,已知一个数列,你需要进行下面两种操作:

  • 将某一个数加上\(x\)
  • 求出某区间每一个数的和

输入格式


第一行包含两个正整数\(n,m\),分别表示该数列数字的个数和操作的总个数。

第二行包含\(n\)个用空格分隔的整数,其中第\(i\)个数字表示数列第\(i\)项的初始值。

接下来\(m\)行每行包含\(3\)个整数,表示一个操作,具体如下:

  • 1 x k 含义:将第\(x\)个数加上\(k\)
  • 2 x y 含义:输出区间\([x,y]\)内每个数的和

输出格式


输出包含若干行整数,即为所有操作\(2\)的结果。


输入输出样例


输入 #1

5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4

输出 #1

14
16

说明/提示


【数据范围】

对于\(30\%\)的数据,\(1 \le n \le 8\)\(1\le m \le 10\)
对于\(70\%\)的数据,\(1\le n,m \le 10^4\)
对于\(100\%\)的数据,\(1\le n,m \le 5\times 10^5\)

样例说明:

故输出结果\(14\)\(16\)



推荐皎月半洒花Senior Data Structure高级数据结构初步·详解分块思想与树状数组

推荐TJor线段树与树状数组


代码


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=5e5+5;
int n,m,c[N];
int lowbit(int x){ return x&(-x); }
void add(int i,int x){
	while(i<=n){
		c[i]+=x;
		i+=lowbit(i);
	}
}
int check(int i){
	int res=0;
	while(i){
		res+=c[i];
		i-=lowbit(i);
	}
	return res;
}
int main(){
	scanf("%d %d",&n,&m);
	for(int x,i=1;i<=n;++i){
		scanf("%d",&x);
		add(i,x);
	}
	for(int x,y,opt,i=1;i<=m;++i){
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d %d",&x,&y);
			add(x,y);
		} else {
			scanf("%d %d",&x,&y);
			printf("%d\n",check(y)-check(x-1));
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Potrem/p/Luogu_P3374.html