P3374 【模板】树状数组 1(单点增减,区间求和)

 

 P3374 【模板】树状数组 1

题目描述

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

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

 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int N = 500100 ;
 5 
 6 int n,m,a;
 7 int ch,x,y,v;
 8 int sum[N];//树状数组 
 9 
10 int lowbit(int x)         
11 {
12     return x&(-x);
13 }
14 
15 void update(int p,int v)    //将第P个数增加v 
16 {
17     while(p<=n)
18     {
19         sum[p] += v;
20         p += lowbit(p);  
21     }    
22 } 
23  
24 int query(int p)    //查询第p个点的值是多少 
25 {
26     int ans=0;
27     while(p)
28     {
29         ans += sum[p];
30         p -= lowbit(p);
31     }
32     return ans;
33 }
34 
35 int main()
36 {
37     ios::sync_with_stdio(false) ;  //输入输出优化 
38     cin>>n>>m;
39     for (int i=1;i<=n;i++) 
40     {
41         cin>>a;
42         update(i,a);  //建树 
43     }
44     for (int i=1;i<=m;++i) 
45     {
46         cin>>ch;
47         if (ch==1)        //单点修改 
48         {
49             cin>>x>>y;
50             update(x,y);
51         }
52         if (ch==2)        //区间查询
53         {
54             cin>>x>>y;            
55             cout<<query(y)-query(x-1)<<endl; 
56         } 
57     }
58     return 0;
59 }
原文地址:https://www.cnblogs.com/mjtcn/p/6831291.html