AcWing 242. 一个简单的整数问题

原题链接

考察:树状数组

确实简单....就是差分+树状数组即可.本蒟蒻还以为又有什么神乎其神的优化.....

思路:

       我们先看第一个指令:第一类指令形如 C l r d,表示把数列中第 l∼r 个数都加 d

        l~r区间内+d .单看这个操作容易想到差分. 即 修改b[l]与b[r+1]

       再看第二个指令:第二类指令形如 Q x,表示询问数列中第 x 个数的值。

       配合上一个指令的差分数组.这里如果考虑差分就是求x的前缀和.

       我们综合来看,修改b数组两个单点的值,求x的前缀和.这正好对应树状数组的操作.因此可以用树状数组优化时间复杂度.

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 typedef long long LL;
 5 const int N = 100010;
 6 LL b[N],m,n,tr[N];
 7 char s[2];
 8 void insert(int l,int r,int x)
 9 {
10     b[l]+=x,b[r+1]-=x;
11 }
12 int lowbit(int x)
13 {
14     return x&-x;
15 }
16 void add(int k,int x)
17 {
18     for(int i=k;i<=n;i+=lowbit(i)) tr[i]+=x;
19 }
20 LL ask(int x)
21 {
22     LL ans = 0;
23     for(int i=x;i;i-=lowbit(i)) ans+=tr[i];
24     return ans;
25 }
26 int main()
27 {
28     scanf("%d%d",&n,&m);
29     for(int i=1;i<=n;i++)
30     {
31         int x; scanf("%d",&x);
32         insert(i,i,x);
33     }
34     for(int i=1;i<=n;i++) add(i,b[i]);
35     while(m--)
36     {
37         int l,r,x;
38         scanf("%s%d",s,&l);
39         if(s[0]=='Q') {printf("%lld\n",ask(l));continue;}
40         scanf("%d%d",&r,&x);
41         add(l,x); add(r+1,-x);
42     }
43     return 0;
44 }

 

posted @ 2021-05-15 01:02  acmloser  阅读(39)  评论(0编辑  收藏  举报