POJ 3468 -- A Simple Problem with Integers ( 树状数组做法 )

题目来源:http://poj.org/problem?id=3468

线段树做法:https://blog.csdn.net/moon_sky1999/article/details/78428165

详解树状数组区间修改、查询操作的博客:

https://ahackh.ac.cn/2017/06/25/%E8%89%AF%E5%BF%83%E8%AF%A6%E8%A7%A3%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84%E3%81%AE%E5%8C%BA%E9%97%B4%E4%BF%AE%E6%94%B9%E6%B1%82%E5%92%8C%E6%9C%89%E8%BF%99%E7%A7%8D%E6%93%8D%E4%BD%9C/

代码:

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn=1e5+10;
ll c1[maxn],c2[maxn],a[maxn];
int n,q;
inline int lb(int x) {
    return x & -x;
}
void add1(int x,ll v) {
    for (; x <= n; x += lb(x))
        c1[x] += v;
}
void add2(int x,ll v) {
    for (; x <= n; x += lb(x))
        c2[x] += v;
}
ll read(int x) {
    ll tot = 0;
    for (int i = x; i; i -= lb(i))
        tot += x * c1[i] - c2[i];
    return tot;
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    while (cin >> n >> q) {
        memset(c1, 0, sizeof(c1));
        memset(c2, 0, sizeof(c2));
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            add1(i, a[i] - a[i - 1]);
            add2(i, (i - 1) * (a[i] - a[i - 1]));
        }
        for (int i = 1; i <= q; i++) {
            char c;
            cin >> c;
            if (c == 'Q') {
                int l, r;
                cin >> l >> r;
                cout << read(r) - read(l - 1) << endl;
            } else {
                int l, r, v;
                cin >> l >> r >> v;
                add1(l, v);
                add1(r + 1, -v);
                add2(l, (l - 1) * v);
                add2(r + 1, r * (-v));
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/moon_sky1999/article/details/81284933
今日推荐