知识点:二分,差分
难度:4
首先,这个题满足单调性,只要中间某个人出现问题,那么相当于后面的人都出现问题了,因为此时要停止教室的分配,显然我们二分的是下标,第几人,然后我选择的是最小化的二分,找最小的停止分配的那个人的下标,然后我们要把无解,也就是不会停止分配考虑进去,最右边加一个下标,接下来就是把求最优解问题转化为判定,我们判定的时候就用到了差分,当前前多少个人,能否分配成功,不能那就返回真,这时按照我的思路写的,如果能分配成功就返回假,
最后需要注意整数溢出的情况,看题目的数据范围
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
long long n, m, a[N], b[N], x[N], y[N], v[N];
bool check(int t) {
long long c[N];
for (int i = 0; i < N; i++) c[i] = b[i];
for (int i = 1; i <= t; i++) {
c[x[i]] -= v[i];
c[y[i] + 1] += v[i];
}
for (int i = 1; i <= n; i++) {
c[i] = c[i - 1] + c[i];
if (c[i] < 0) return true;
}
return false;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
b[i] = a[i] - a[i - 1];
}
for (int i = 1; i <= m; i++) {
cin >> v[i] >> x[i] >> y[i];
}
int l = 1, r = m + 1;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
if (l == m + 1) cout << 0;
else cout << -1 << endl << l;
return 0;
}