视频讲解: https://www.bilibili.com/video/BV1WDrnBPEKN/

维基百科: https://oi-wiki.org/ds/fenwick/#thetan-%E5%BB%BA%E6%A0%91

例题: https://www.luogu.com.cn/problem/P3374

#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cmath>
#include <vector>
#include <queue>
#include <climits>

using namespace std;
typedef long long ll;

int n, m, a[600000], c[600000]; 

// 计算lowbit
int lowbit(int x) {
    return x & (-x);
}

// 计算前缀和
int query(int x) {
    int ans = 0;
    while (x > 0) {
        ans += c[x];
        x -= lowbit(x);
    }
    return ans;
}

// 从当前位置依次向后加x
void change(int pos, int delta) {
    while (pos <= n) {
        c[pos] += delta;
        pos += lowbit(pos);
    }
}

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

    // O(n) 建树
    for (int i = 1; i <= n; i++) {
        c[i] += a[i];
        int j = lowbit(i) + i;
        if (j <= n) c[j] += c[i];
    }

    for (int i = 1; i <= m; i++) {
        int tp, x, y;
        cin >> tp >> x >> y;
        if (tp == 1) {
            change(x, y); // 将位置 x 增加 y
        } else if (tp == 2) {
            // 区间和 = 前缀和(y) - 前缀和(x-1)
            cout << query(y) - query(x - 1) << endl;
        }
    }
    return 0;
}

haihaihai

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注