luogu P2376 语文成绩
语文成绩
题目背景
语文考试结束了,成绩还是一如既往地有问题。
题目描述
语文老师总是写错成绩,所以当她修改成绩的时候,总是累得不行。她总是要一遍遍地给某些同学增加分数,又要注意最低分是多少。你能帮帮她吗?
输入格式
第一行有两个整数 \(n\),\(p\),代表学生数与增加分数的次数。
第二行有 \(n\) 个数,\(a_1 \sim a_n\),代表各个学生的初始成绩。
接下来 \(p\) 行,每行有三个数,\(x\),\(y\),\(z\),代表给第 \(x\) 个到第 \(y\) 个学生每人增加 \(z\) 分。
输出格式
输出仅一行,代表更改分数后,全班的最低分。
样例
3 2
1 1 1
1 2 1
2 3 1
2
数据范围
对于 \(100\%\) 的数据,有 \(n \le 5\times 10^6\),\(p \le n\),学生初始成绩 \(\le 100\),\(z \le 100\)。
思路
给[a, b]区间的所有数加上z,很麻烦。
若给差分数组的第a项加上z,再让第b + 1 项减去z,那么前缀和便完成了这一区间都加上z的操作,所以可以一开始将分数作为前缀和
小tips
全部用scanf和printf会快至少500ms
代码
#include <iostream>
const int N = 5e6 + 10;
int s[N], a[N];
using namespace std;
int main()
{
int n, q; scanf("%d %d", &n, &q);
for(int i = 1; i <= n; i++)
{
cin >> s[i];
a[i] = s[i] - s[i - 1];
}
while(q--)
{
int x, y, z; scanf("%d %d %d", &x, &y, &z);
a[x] += z, a[y + 1] -= z;
}
int min = 5e6;
for(int i = 1; i <= n; i++)
{
s[i] = a[i] + s[i - 1];
min = s[i] < min ? s[i] : min;
}
printf("%d", min);
}