区间修改 + 区间查询(树状数组)
结构:树状数组
参考博客:https://blog.csdn.net/zars19/article/details/54620021
题目:codev1082 线段树练习 3
http://codevs.cn/problem/1082/
代码:
#include <iostream> #include <cstdio> using namespace std; #define lowbit(x) (x&(-x)) const int maxn = 2e5+7; typedef long long ll; ll sum[maxn]; //原始前缀和数组 ll delta[maxn]; //delta前缀和数组 ll delta_i[maxn]; //delta * i 前缀和数组 int n, m; void update(ll *r, int x, int val) { for(int i = x; i <= n; i += lowbit(i)) { r[i] += val; } } ll query(ll *r, int x) { ll res = 0; for(int i = x; i > 0; i -= lowbit(i)) { res += r[i]; } return res; } int main () { scanf("%d", &n); for(int i = 1;i <= n; i++) { scanf("%lld", &sum[i]); sum[i] += sum[i - 1]; } scanf("%d", &m); while(m--) { int op, l, r, w; scanf("%d", &op); if(op == 1) { scanf("%d %d %d", &l, &r, &w); update(delta, l, w); update(delta, r + 1, -w); update(delta_i, l, l * w); update(delta_i, r + 1, (r + 1) * (-w)); } else { scanf("%d %d", &l, &r); ll suml = sum[l - 1] + l * query(delta, l - 1) - query(delta_i, l - 1); //这个是[1, left - 1]通过那个公式求出来得和 ll sumr = sum[r] + (r + 1) * query(delta, r) - query(delta_i, r); //这个是[1, right]通过那个公式求出来得和 printf("%lld\n", sumr - suml); } } return 0; }