[AcWing] 一个简单的整数问题

一个简单的整数问题

题目

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

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

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

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

输入格式

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

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

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

输出格式

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

每个答案占一行。

数据范围

1 N , M 105 d 10000 A [ i ] 1000000000 1≤N,M≤105 \\ |d|≤10000\\ |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

题解

思路

  • 普通树状数组只支持单点修改和查询前缀和(因此也可以求区间和)

  • 所以我们考虑用树状数组维护差分序列

  • 那么区间修改就相当于单点修改,求某个数相当于求差分数组前缀和

  • 差分链接

#include <iostream>

using namespace std;

const int N = 1e5 + 20;
int n, m, a[N], tr[N];

inline int lowbit(int x) {
    return x & -x;
}

void add(int x, int t) {
    for (; x <= n; x += lowbit(x)) tr[x] += t;
}

int sum(int x) {
    int res = 0;
    for (; x; x -= lowbit(x)) res += tr[x];
    return res;
}

int main () {
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    for (int i = 1; i <= n; i ++) add(i, a[i] - a[i-1]);

    char ch;
    int l, r, c;
    while (m --) {
        cin >> ch;
        if (ch == 'Q') {
            cin >> c;
            cout << sum(c) << endl;
        }
        else {
            cin >> l >> r >> c;
            add(l, c), add(r + 1, -c);
        }
    }

    return 0;
}
发布了83 篇原创文章 · 获赞 1 · 访问量 5907

猜你喜欢

转载自blog.csdn.net/weixin_44922845/article/details/104558364