欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

树状数组Binary Indexed Tree(2):区间修改,单点查询

程序员文章站 2024-03-03 15:48:28
...

Description

给定数列a[1],a[2]…,a[n],需要依次执行q个操作。
操作分两类:
1 l r x : 给定l,r,x,对于所有 i ∈ \in [l,r],将a[i]加上x
2 i :求a[i]的值
(1 ≤ \leq n,q ≤ \leq 106)

解题思路

算法标签:树状数组
利用差分的思想。设原数组number[i],d[i] = number[i] - number[i-1],所以number[i] = ∑ j = 1 i d [ j ] \sum_{j=1}^id[j] j=1id[j],即可以通过求d[i]的前缀和查询。修改通过给d[l]加上x,给d[r+1]减上x

代码

// TSWorld
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 1000009;

long long tree[N];
int number[N];
int n, q;

inline int lowbit(long long x) { return x & (-x); }
void Change(int index, int delta) {
    while (index <= n) {
        tree[index] += delta;
        index += lowbit(index);
    }
}

long long Query(long long index) {
    long long sum = 0;

    while (index > 0) {
        sum += tree[index];
        index -= lowbit(index);
    }
    return sum;
}
int main() {
    int cmd = 0, l = 0, r = 0, x = 0;
    cin >> n >> q;

    for (int i = 1; i <= n; i++) {
        scanf("%d", &number[i]);
        Change(i, number[i] - number[i - 1]);
    }

    for (int i = 1; i <= q; i++) {
        scanf("%d", &cmd);

        if (cmd == 1) {
            scanf("%d%d%d", &l, &r, &x);
            Change(l, x);
            Change(r + 1, -x);
        } else {
            scanf("%d", &l);
            printf("%lld\n", Query(l));
        }
    }

    return 0;
}