ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LOJ132. 树状数组 3 :区间修改,区间查询 题解

2021-11-27 10:03:19  阅读:110  来源: 互联网

标签:limits int 题解 sum t2 long add 区间 LOJ132


题目链接: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

标签:limits,int,题解,sum,t2,long,add,区间,LOJ132
来源: https://www.cnblogs.com/quanjun/p/15610675.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有