SP16487题解

思路

区间查询,自然就想到差分。大佬的线段树我看不懂,我就用差分来解决这道题。

我们用

首先如何修改部分数组的每个数值?

我们很容易地发现修改部分数组中,区间中每一个数字和前后数字的差只有第一个和最后一个变了。我们可以先将数组 x x x 设为全部为 0 0 0(全是 0 0 0 的数组相减后自然全部为 0 0 0),每次修改我们将数组进行如下处理:

  • x l ← x l + v a l x_l \gets x_l + val xlxl+val
  • x r + 1 ← x r + 1 − v a l x_{r + 1} \gets x_{r + 1} - val xr+1xr+1val
    这样就修改了差分数组。

差分数组如何变成原数组?

对于数组中的每一个数字,我们只要从 1 1 1 n − 1 n - 1 n1 x i + x i − 1 x_i + x_{i - 1} xi+xi1,就得到了原数组(前缀和)。

代码

洛谷上AC记录

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<map>

using namespace std;
int x[10005];
// 快读
inline int read()
{
	int x = 0,f = 1;char ch = getchar();
	while (ch < '0' or ch > '9'){if (ch == '-') f = -1;ch = getchar();}
	while (ch >= '0' and ch<='9'){x = x * 10 + ch - 48;ch = getchar();}
	return x * f;
}
//快写
inline void write(int x) {
	if(x < 0) putchar('-'),x = -x;
	if(x > 9) write(x / 10);
	putchar(x % 10 + '0');
	return;
}
//输出char
void writec(char x) {
	putchar(x);
	return;
}
int main() {
	int t = read();
	while(t--) {
		int n = read(),u = read();
		//初始化查分数组
		for(int i = 0;i < n;i++) x[i] = 0;
		//修改 
		while(u--) {
			int l = read(),r = read(),val = read();
			x[l] += val;
			x[r + 1] -= val;
		}
		//前缀和复原数组 
		for(int i = 1;i < n;i++) x[i] += x[i - 1];
		//输出 
		int q = read();
		while(q--) {
			int i = read();
			write(x[i]),writec('\n');
		}
	}
    return 0;
}

差分模板题目

Update

2022/12/22 完成题解

2022/12/24 修改题解(感谢大佬指导指出,将 x 1 x1 x1 改成 x l x_l xl

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值