共有n名学生的语文成绩要登记,目前登记的成绩是a[1],a[2],…,a[n]。但是语文老师lester写错了不少成绩,所以他要修改成绩的时候,总是累得不行。现在他要修改p次:每次修改行为由三个数字x,y,z表示,代表第x个到第y个学生每人增加z分。他总是要一遍遍地给某些同学增加分数,又要注意最低分是多少。你能帮帮他吗 输入输出格式 输入格式 第一行有两个正整数n和p(p<=n<=500000),代表学生数与加分次数 第二行有n个正整数,a[1],a[2],…a[n],代表各个学生的初始成绩(均不超过100) 接下来p行,每行有三个正整数,x,y,z,代表给第x个到第y个学生每人增加z分(x,y<=n, z<=100)。注意x可能大于y。 输出格式 输出一行,代表更改分数后,全班的最低分是几分。
时间: 2024-02-29 14:57:17 浏览: 142
以下是 C++ 的代码实现:
```cpp
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 500010;
int n, m;
int a[N];
int tr[N << 2];
void pushup(int u) {
tr[u] = min(tr[u << 1], tr[u << 1 | 1]);
}
void build(int u, int l, int r) {
if (l == r) tr[u] = a[l];
else {
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(int u, int l, int r, int x, int y, int k) {
if (l >= x && r <= y) tr[u] += k;
else {
int mid = l + r >> 1;
if (x <= mid) modify(u << 1, l, mid, x, y, k);
if (y > mid) modify(u << 1 | 1, mid + 1, r, x, y, k);
pushup(u);
}
}
int query(int u, int l, int r, int x, int y) {
if (l >= x && r <= y) return tr[u];
else {
int mid = l + r >> 1, res = 0x3f3f3f3f;
if (x <= mid) res = min(res, query(u << 1, l, mid, x, y));
if (y > mid) res = min(res, query(u << 1 | 1, mid + 1, r, x, y));
return res;
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
while (m--) {
int l, r, k;
cin >> l >> r >> k;
modify(1, 1, n, l, r, k);
}
cout << query(1, 1, n, 1, n) << endl;
return 0;
}
```
算法流程:
1. 读入数据,建立线段树,每个节点维护区间最小值。
2. 对于每次操作,将对应区间的值修改,然后更新线段树。
3. 最后输出整个区间的最小值。
时间复杂度:$O(m \log n)$。
阅读全文