2

洛谷 P3374 【模板】树状数组 1 题解

题目描述

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

  • 将某一个数加上 x

  • 求出某区间每一个数的和

输入格式

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

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

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

  • 1 x k 含义:将第 x 个数加上 k

  • 2 x y 含义:输出区间 [x,y] 内每个数的和

输出格式

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

AC代码:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 
 5 ll n,m,a[500001],c[500001];
 6 
 7 int lowbit(int x)
 8 {
 9     return x&(-x);
10 }
11 
12 void updata(int k,int v)
13 {
14     while (k<=n)
15     {
16         c[k]+=v;
17         k+=lowbit(k);
18     }
19 }
20 
21 int getsum(int k)
22 {
23     int ans=0;
24     while (k>0)
25     {
26         ans+=c[k];
27         k-=lowbit(k);
28     }
29     return ans;
30 }
31 
32 int main()
33 {
34     scanf("%lld%lld",&n,&m);
35     for (int i=1;i<=n;i++)
36     {
37         scanf("%lld",&a[i]);
38         updata(i,a[i]);
39     }
40     while (m--)
41     {
42         int op,x,y;
43         cin>>op>>x>>y;
44         if (op==1)
45             updata(x,y);
46         if (op==2)
47         {
48             int sum=getsum(y)-getsum(x-1);
49             printf("%d\n",sum);
50         }
51     }
52     return 0;
53 }

 

posted @ 2021-08-18 11:17  Zˇx  阅读(43)  评论(0)    收藏  举报
Live2D