1 条题解
-
0
树状数组
$$∑_{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
- 上传者