差分法,c语言

差分法思想

如果我们想将红色框选区间(数组对应下标为2至5)数据全部加1。只需要将下标为2的差分数组的数据加一,将下标为6的差分数组的数据减一。

如果我们想将绿色框选区间(数组对应下标为0至3)数据全部加2。只需要将下标为0的差分数组的数据加2,将下标为4的差分数组的数据减2。

我们可以总结出规律:

我们想要让num数组i到j的数据都加n,需要其差分数组defferNum[ i ]+=n, defferNum[j+1] -= n,

有了差分法思想,当然要实践啊

例题

语文老师总是写错成绩,所以当她修改成绩的时候,总是累得不行。

她总是要一遍遍地给某些同学增加分数,又要注意最低分是多少。你能帮帮她吗?

输入格式

第一行,两个整数n,m,代表学生总数和增加分数的次数。

第二行,n个整数,代表每个学生的初始成绩。

接下来m行,每行有三个整数x,y,z,代表给第x个到第y个学生每人增加z分。

输出格式

输出仅一行,代表更改分数后,全班的最低分。

数据范围

1 ≤ n ≤ 1, 000, 000,m ≤ n,学生初始成绩 ≤ 100,z ≤ 100(成绩可以大于100)

输入数据 3 2

1 1 1

1 2 1

2 3 1

输出数据 2

如果暴力求解,将数组区间用for循环遍历加一,但是如果我们的n足够大, 逼如恰好等于1, 000, 000,则需要遍历1000000次,一定是超时的。

#include <stdio.h>
#include <limits.h>//INT_MAX关键字的头文件
int num[1000010];  //成绩
int differ[1000010];  //差分数组
int main()
{
	int n, m, min = INT_MAX;//INT_MAX是整形的最大值,
//因为成绩是可以很大的,我们需要将min赋最大值,为后面作比较
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		scanf("%d", &num[i]);
		if (i == 0) differ[i] = num[i];  //第一个数直接赋值
		differ[i] = num[i] - num[i - 1];
	}
	while (m--) {
		int x, y, z;
		scanf("%d %d %d", &x, &y, &z);
		differ[x - 1] += z;
		if (y < n) {  //考虑极端情况
			differ[y] -= z;
		}
	}

	//还原
	num[0] = differ[0];//o下标需要直接赋值
	if (num[0] < min)//将num[0]与min作比较
		min = num[0];
	for (int i = 1; i < n; i++) {
		num[i] = differ[i] + num[i - 1];
		if (num[i] < min) {
			min = num[i];
		}
	}
	printf("%d", min);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值