• 树状数组plus


    (A_i) 是原数组, (d_i = A_i - A_{i-1})(A) 的差分数组

    [S_n = sum_{i=1}^nA_i = d_1 + \d_1 + d_2 +\ d_1 + d_2 + d_3 + \ ... \d_1 + d_2 + d_3 + d_4 + ... + d_n \ = n (d_1 + d_2 + ... + d_n) - sum_{i=1}^nd_i(i-1) ]

    (B_i = d_i(i-1))

    [S_n = nsum d - sum B ]

    而当一段区间 ([L,R]) 一起加上 (x) 的时候,

    对于 (d) 来说,只有 (d_L)(d_{R+1}) 发生了变化

    对于 (B) 来说,也是同理,所以可以开两个树状数组来进行维护

    【模板】线段树1

    /*
     * @Author: zhl
     * @Date: 2020-11-17 10:33:57
     */
    #include<bits/stdc++.h>
    using ll = long long;
    using namespace std;
    
    const int N = 1e5 + 10;
    int n, m;
    struct{
    	ll C[N][2]; // 0 是差分d_i , 1 是 d_i * (i - 1)
    	void add(int pos, ll val, int o) {
    		for (; pos <= n; pos += (-pos) & pos) C[pos][o] += val;
    	}
    	ll ask(int pos, int o) {
    		ll ans = 0;
    		for (; pos; pos -= (-pos) & pos) ans += C[pos][o];
    		return ans;
    	}
    
    	void updt(int l, int r, int x) {
    		add(l, x, 0); add(r + 1, -x, 0);
    		add(l, x * (l - 1), 1); add(r + 1, -x * (r), 1);
    	}
    	ll query(int l, int r) {
    		ll R = r * ask(r, 0) - ask(r, 1);
    		ll L = (l - 1) * ask(l - 1, 0) - ask(l - 1, 1);
    		return R - L;
    	}
    }BIT;
    
    int main() {
    	scanf("%d%d", &n, &m);
    	int pre = 0;
    	for (int i = 1; i <= n; i++) {
    		int x; scanf("%d", &x);
    		BIT.add(i,x - pre,0);
    		BIT.add(i, 1ll * (x - pre)* (i - 1), 1);
    		pre = x;
    	}
    	while (m--) {
    		int op, a, b, x;
    		scanf("%d", &op);
    		if (op == 1) {
    			scanf("%d%d%d", &a, &b, &x);
    			BIT.updt(a, b, x);
    		}
    		else {
    			scanf("%d%d", &a, &b);
    			printf("%lld
    ", BIT.query(a, b));
    		}
    	}
    }
    
  • 相关阅读:
    Linux使用手册
    Oracle&SQL使用记录
    docker的使用
    springboot与mybatis
    JavaScript与TypeScript总结
    React总结
    React与jsplumb
    DB2入门
    吾尝终日而思矣——2019.02.17
    吾尝终日而思矣——2019.02.12
  • 原文地址:https://www.cnblogs.com/sduwh/p/13994080.html
Copyright © 2020-2023  润新知