zoukankan      html  css  js  c++  java
  • LOJ132. 树状数组 3 :区间修改,区间查询 题解

    题目链接:https://loj.ac/p/132

    解题思路:

    设元素组元素为 \(a_i\),其方差数组为 \(d_i = a_i - a_{i-1}\)

    \(a_x = \sum\limits_{i=1}^{x} d_i\)

    所以有 \(\sum\limits_{i=1}^{x} a_i = \sum\limits_{i=1}^{x} \sum\limits_{j=1}^{i} d_j = \sum\limits_{i=1}^x (x-i+1) \times d_i\)

    于是有 \(\sum\limits_{i=1}^x = (x+1) \sum\limits_{i=1}^x d_i - \sum\limits_{i=1}^x d_i \times i\)

    于是将原数组差分后维护两个树状数组,一个维护 \(d_i\),一个维护 \(d_i \times i\)。即可解决这个问题。

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1000010;
    int n, q, op, l, r;
    long long x, a[maxn];
    
    struct BIT {
    	long long c[maxn];
    	int lowbit(int x) {
    		return x & -x;
    	}
    	void add(int p, long long x) {
    		while (p <= n) {
    			c[p] += x;
    			p += lowbit(p);
    		}
    	}
    	long long query(int p) {
    		long long res = 0;
    		while (p) {
    			res += c[p];
    			p -= lowbit(p);
    		}
    		return res;
    	}
    } t1, t2;
    
    int main()
    {
    	cin >> n >> q;
    	for (int i = 1; i <= n; i ++) {
    		cin >> a[i];
    		t1.add(i, a[i]-a[i-1]);
    		t2.add(i, (a[i]-a[i-1])*i);
    	}
    	while (q --) {
    		cin >> op >> l >> r;
    		if (op == 1) {
    			cin >> x;
    			t1.add(l, x);
    			t1.add(r+1, -x);
    			t2.add(l, x*l);
    			t2.add(r+1, -x*(r+1));
    		}
    		else {
    			long long rval = (r+1) * t1.query(r) - t2.query(r);
    			long long lval = l* t1.query(l-1) - t2.query(l-1);
    			cout << rval - lval << endl;
    		}
    	}
    	return 0;
    }
    

    参考链接:https://www.cnblogs.com/lcf-2000/p/5866170.html

  • 相关阅读:
    架构漫谈1
    如何将本地工程上传到github
    寒假日报day23
    寒假日报----首都之窗爬虫大作业
    寒假日报day22
    寒假日报day21
    关于webmagic的post请求
    寒假日报day20
    寒假日报day19
    吾日三省吾身(41)
  • 原文地址:https://www.cnblogs.com/quanjun/p/15610675.html
Copyright © 2011-2022 走看看