AcWing:242. 一个简单的整数问题(树状数组)

Posted buhuiflydepig

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing:242. 一个简单的整数问题(树状数组)相关的知识,希望对你有一定的参考价值。

给定长度为N的数列A,然后输入M行操作指令。

第一类指令形如“C l r d”,表示把数列中第l~r个数都加d。

第二类指令形如“Q X”,表示询问数列中第x个数的值。

对于每个询问,输出一个整数表示答案。

输入格式

第一行包含两个整数N和M。

第二行包含N个整数A[i]。

接下来M行表示M条指令,每条指令的格式如题目描述所示。

输出格式

对于每个询问,输出一个整数表示答案。

每个答案占一行。

数据范围

1N,M1051≤N,M≤105,
|d|10000|d|≤10000,
|A[i]|1000000000|A[i]|≤1000000000

输入样例:

10 5
1 2 3 4 5 6 7 8 9 10
Q 4
Q 1
Q 2
C 1 6 3
Q 2

输出样例:

4
1
2
5

 

题解:利用树状数组来记录每次改变的值,如果修改[l, r]之间的值,增加val,则令[l, n]加上val,[r + 1, n]减去val,然后查询值得时候,就是用树状数组得查询,然后加上原来数组里面得值就是答案。

 

#include <iostream>
#include <cstdio>

using namespace std;

typedef long long ll;

const int maxn = 1e5+7;

ll arr[maxn];
ll tree[maxn];
int n, m;

int lowbit(int x) 
    return x & (-x);


void add(int x, ll val) 
    while(x <= n) 
        tree[x] += val;
        x += lowbit(x);
    


ll ask(int x) 
    ll res = 0;
    while(x >= 1) 
        res += tree[x];
        x -= lowbit(x);
        
    return res;


int main() 
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) 
        scanf("%lld", &arr[i]);
    
    while(m--) 
        char str[5];
        int l, r;
        ll val;
        scanf("%s", str);
        if(str[0] == Q) 
            scanf("%d", &l);
            printf("%lld\n", ask(l) + arr[l]);
         else 
            scanf("%d%d%lld", &l, &r, &val);
            add(l, val);    //在[l, n]的区间内增加val
            add(r + 1, -val);    //在[r + 1, n]的区间内减少val
        
    
    return 0;    

 

以上是关于AcWing:242. 一个简单的整数问题(树状数组)的主要内容,如果未能解决你的问题,请参考以下文章

242. 一个简单的整数问题树状数组的简单扩展 区间修改 单点查询

AcWing 242 一个简单整数问题(区间修改 单点查询)

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

242. 一个简单的整数问题树状数组 区间加 单点和

acwing 243. 一个简单的整数问题2 树状数组 线段树

AcWing提高算法课Level-3 第四章 高级数据结构