【洛谷 P2367】语文成绩 题解(差分)

文章介绍如何通过编程实现差分数组技术解决语文成绩修改问题,快速找到全班最低分。
摘要由CSDN通过智能技术生成

语文成绩

题目背景

语文考试结束了,成绩还是一如既往地有问题。

题目描述

语文老师总是写错成绩,所以当她修改成绩的时候,总是累得不行。她总是要一遍遍地给某些同学增加分数,又要注意最低分是多少。你能帮帮她吗?

输入格式

第一行有两个整数 n n n p p p,代表学生数与增加分数的次数。

第二行有 n n n 个数, a 1 ∼ a n a_1 \sim a_n a1an,代表各个学生的初始成绩。

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

输出格式

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

样例 #1

样例输入 #1

3 2
1 1 1
1 2 1
2 3 1

样例输出 #1

2

提示

对于 40 % 40\% 40% 的数据,有 n ≤ 1 0 3 n \le 10^3 n103

对于 60 % 60\% 60% 的数据,有 n ≤ 1 0 4 n \le 10^4 n104

对于 80 % 80\% 80% 的数据,有 n ≤ 1 0 5 n \le 10^5 n105

对于 100 % 100\% 100% 的数据,有 n ≤ 5 × 1 0 6 n \le 5\times 10^6 n5×106 p ≤ n p \le n pn,学生初始成绩 $ \le 100 , , z \le 100$。


思路

差分数组是一种经常用于处理区间修改的数据结构,其主要思想是将连续的问题转化为离散的问题。

首先定义一个原数组a和一个差分数组d。差分数组的定义是d[i] = a[i] - a[i - 1],即每个元素都是当前元素与前一个元素的差值。

然后,程序接收用户输入的数据,其中n是数组的长度,p是要进行的操作次数。对于每次操作,用户输入三个数xyz,代表将数组的第x个元素到第y个元素都增加z。在差分数组中,这可以通过将d[x]增加zd[y + 1]减少z来实现。这样,当我们后续遍历差分数组并累加时,从xy的元素都会增加z,而从y + 1开始的元素则不会受影响,实现了区间的修改。

最后,程序遍历差分数组并累加,得到新的a数组,同时找出并输出数组中的最小值。这里的遍历累加过程就是差分数组转换回原数组的过程。


AC代码

#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;

const int N = 1e7 + 7;

int n, p;
int a[N], d[N];

int main() {
	a[0] = 0;
	cin >> n >> p;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		d[i] = a[i] - a[i - 1];
	}
	for (int i = 1; i <= p; i++) {
		int x, y, z;
		cin >> x >> y >> z;
		d[x] += z;
		d[y + 1] -= z;
	}
	int min = 0x3f3f3f3f;
	for (int i = 1; i <= n; i++) {
		a[i] = a[i - 1] + d[i];
		min = (a[i] < min) ? a[i] : min;
	}
	cout << min << endl;
	return 0;
}
  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值