3391. 线段树:区间增加

帕秋莉_诺蕾姬

树状数组拓展:区间修改 来源:https://blog.csdn.net/fsahfgsadhsakndas/article/details/52650026

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x & -x
typedef long long ll;
const int M = 500005;
ll num[M], c1[M], c2[M];
int n, m;
void add(ll *r, int x, ll val) {
    for (int i = x; i <= n; i += lowbit(i))
        r[i] += val;
}
void add(ll x, ll y, ll k) {
    add(c1, x, k); add(c1, y + 1, -k);
    add(c2, x, k*(x - 1)); add(c2, y + 1, -k * y);
}
ll sigma(ll *r , int x) {
    ll sum = 0;
    for (int i = x; i; i -= lowbit(i))
        sum += r[i];
    return sum;
}
ll sum(ll x, ll y) {
    ll sum1 = (x - 1)*sigma(c1, x - 1) - sigma(c2, x - 1),
        sum2 = y * sigma(c1, y) - sigma(c2, y);
    return sum2 - sum1;
}
int main(){
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        scanf("%lld", &num[i]);
        add(c1, i, num[i] - num[i - 1]);
        add(c2, i, (i - 1)*(num[i] - num[i - 1]));
    }
    cin >> m; 
    ll com, x, y, k;
    while (m--) {
        cin >> com;
        if (com == 1)
            scanf("%lld%lld%lld", &x, &y, &k), add(x, y, k);
        else
            scanf("%lld%lld", &x, &y), printf("%lld\n", sum(x, y));
    }
}
你当前正在回复 博客/题目
存在问题!