P2367 语文成绩——差分、前缀和

题目背景

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

题目描述

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

输入格式

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

第二行有 \(n\) 个数,\(a_1 \sim a_n\),代表各个学生的初始成绩。

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

输出格式

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

输入输出样例 #1

输入 #1

3 2
1 1 1
1 2 1
2 3 1

输出 #1

2

说明/提示

对于 \(40\%\) 的数据,有 \(n \le 10^3\)

对于 \(60\%\) 的数据,有 \(n \le 10^4\)

对于 \(80\%\) 的数据,有 \(n \le 10^5\)

对于 \(100\%\) 的数据,有 \(n \le 5\times 10^6\)\(p \le n\),学生初始成绩 $ \le 100\(,\)z \le 100$。

题解

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n, p;
// 读取学生数量 n 和增加分数的次数 p
cin >> n >> p;
// 存储每个学生的初始成绩
vector<int> scores(n);
for (int i = 0; i < n; ++i) {
cin >> scores[i];
}
// 初始化差分数组,长度为 n + 1,初始值都为 0
vector<int> diff(n + 1, 0);
// 进行区间修改操作
for (int i = 0; i < p; ++i) {
int x, y, z;
cin >> x >> y >> z;
// 差分数组区间修改,注意下标从 0 开始,所以 x - 1
diff[x - 1] += z;
if (y < n) {
diff[y] -= z;
}
}
// 还原修改后的成绩数组
for (int i = 1; i < n; ++i) {
diff[i] += diff[i - 1];
scores[i] += diff[i];
}
scores[0] += diff[0];
// 找出最低分
int min_score = *min_element(scores.begin(), scores.end());
// 输出结果
cout << min_score << endl;
return 0;
}

代码解释:

  1. 输入处理
    • 首先读取学生数量 n 和增加分数的次数 p
    • 接着使用 vector 存储每个学生的初始成绩。
    • 再创建一个长度为 n + 1 的差分数组 diff,并初始化为 0。
  2. 区间修改
    • 循环 p 次,每次读取区间 [x, y] 和要增加的分数 z
    • 在差分数组中,将 diff[x - 1] 加上 z,如果 y 小于 n,则将 diff[y] 减去 z
  3. 还原数组
    • 通过前缀和的方式将差分数组还原为修改后的成绩数组。从第二个元素开始,diff[i] 等于它本身加上 diff[i - 1],同时将这个差值加到 scores[i] 上。
    • 对于第一个元素,直接将 diff[0] 加到 scores[0] 上。
  4. 找出最低分
    • 使用 min_element 函数找出 scores 数组中的最小值。
  5. 输出结果
    • 输出修改后的最低分。
发布于   xiins  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示