zoukankan      html  css  js  c++  java
  • 树状数组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));
    		}
    	}
    }
    
  • 相关阅读:
    HTML DOM 12 表格排序
    HTML DOM 10 常用场景
    HTML DOM 10 插入节点
    HTML DOM 09 替换节点
    HTML DOM 08 删除节点
    HTML DOM 07 创建节点
    022 注释
    024 数字类型
    005 基于面向对象设计一个简单的游戏
    021 花式赋值
  • 原文地址:https://www.cnblogs.com/sduwh/p/13994080.html
Copyright © 2011-2022 走看看