1 条题解

  • 0
    @ 2024-10-5 18:40:09

    树状数组

    $$∑_{i=1}^x∑_{j=1}^ib_j = ∑_{i=1}^x(x−i+1)×b_i = (x+1)∑_{i=1}^xb_i−∑_{i=1}^x i×b_i $$

    因此只需维护两个树状数组即可

    一个是差分数组d[i]的树状数组tr1[i],一个是i*d[i]的树状数组tr2[i]。

    #include <bits/stdc++.h>
    using namespace std;
    #define lowbit(x) (x & (-x))
    typedef long long ll;
    const int N = 1e6 + 10, INF = 0x3f3f3f3f;
    int n, m, a[N];
    ll tr1[N], tr2[N];
    void add(ll tr[], int x, ll y) {
        for (int i = x; i <= n; i += lowbit(i))
            tr[i] += y;
    }
    ll query(ll tr[], ll x) {
        ll res = 0;
        for (int i = x; i; i -= lowbit(i))
            res += tr[i];
        return res;
    }
    ll pre(int x) {
        return query(tr1, x) * (x + 1) - query(tr2, x);
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            ll b = a[i] - a[i - 1];
            add(tr1, i, b), add(tr2, i, i * b);
        }
        char op[10];
        int l, r, d;
        while (m--) {
            scanf("%s%d%d", op, &l, &r);
            if (*op == 'Q') {
                printf("%lld\n", pre(r) - pre(l - 1));
            } else {
                scanf("%d", &d);
                add(tr1, l, d), add(tr2, l, l * d);
                add(tr1, r + 1, -d), add(tr2, r + 1, -(r + 1) * d);
            }
        }
        return 0;
    }
    
    
    • 1

    信息

    ID
    1545
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者