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);
}
posted @ 2024-11-17 15:00  PeachyGalaxy  阅读(20)  评论(0编辑  收藏  举报