P3374 【模板】树状数组 1
- 时空限制1s / 128MB
题目描述
如题,已知一个数列,你需要进行下面两种操作:
1.将某一个数加上x
2.求出某区间每一个数的和
输入输出格式
输入格式:
第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。
第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
接下来M行每行包含3或4个整数,表示一个操作,具体如下:
操作1: 格式:1 x k 含义:将第x个数加上k
操作2: 格式: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
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=10000,M<=10000
对于100%的数据:N<=500000,M<=500000
样例说明:
故输出结果14、16
-------------------------------------------------------------------------------------------------------------
推一篇博客:http://blog.csdn.net/qq_21841245/article/details/43956633
非常本职的树状数组,存个板子
1 #include<stdio.h> 2 #include<string.h> 3 #define maxn 500010 4 int delta[maxn],n,m,sum[maxn]; 5 int read(); 6 int find(int); 7 void add(int,int); 8 int lowbit(int); 9 int main(){ 10 n=read();m=read(); 11 for(int i=1;i<=n;i++){ 12 int a=read(); 13 sum[i]=sum[i-1]+a; 14 } 15 for(int i=1;i<=m;i++){ 16 int o=read(),x=read(),y=read(); 17 if(o==1) add(x,y); 18 else{ 19 int ans=find(y)-find(x-1)+sum[y]-sum[x-1]; 20 printf("%d\n",ans); 21 } 22 } 23 return 0; 24 } 25 int find(int x){ 26 int SUM=0; 27 while(x>0){ 28 SUM+=delta[x]; 29 x-=lowbit(x); 30 } 31 return SUM; 32 } 33 void add(int x,int k){ 34 while(x<=n){ 35 delta[x]+=k; 36 x+=lowbit(x); 37 } 38 } 39 int lowbit(int x){ 40 return x&-x; 41 } 42 int read(){ 43 int ans=0,f=1;char c=getchar(); 44 while(‘0‘>c||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 45 while(‘0‘<=c&&c<=‘9‘)ans=ans*10+c-48,c=getchar();return ans*f; 46 }
单点修改+区间查询
时间: 2024-10-11 05:57:43