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; }
代码解释:
- 输入处理:
- 首先读取学生数量
n
和增加分数的次数p
。 - 接着使用
vector
存储每个学生的初始成绩。 - 再创建一个长度为
n + 1
的差分数组diff
,并初始化为 0。
- 首先读取学生数量
- 区间修改:
- 循环
p
次,每次读取区间[x, y]
和要增加的分数z
。 - 在差分数组中,将
diff[x - 1]
加上z
,如果y
小于n
,则将diff[y]
减去z
。
- 循环
- 还原数组:
- 通过前缀和的方式将差分数组还原为修改后的成绩数组。从第二个元素开始,
diff[i]
等于它本身加上diff[i - 1]
,同时将这个差值加到scores[i]
上。 - 对于第一个元素,直接将
diff[0]
加到scores[0]
上。
- 通过前缀和的方式将差分数组还原为修改后的成绩数组。从第二个元素开始,
- 找出最低分:
- 使用
min_element
函数找出scores
数组中的最小值。
- 使用
- 输出结果:
- 输出修改后的最低分。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了