You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
3.5 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
#define int long long
#define endl "\n"
2 years ago
int n, m; // 天数和订单的数量
int r[N]; // 第i天学校有r[i]个教室可借用
int d[N], s[N], t[N]; // 借的教室数目、从第s天借到t天
int b[N]; // 差分数组
bool check(int mid) { // 判断能不能通过前mid个订单
memset(b, 0, sizeof b); // 每次判断都要先初始化差分数组
int sum = 0; // 记录需要借的教室数
// ① 构建差分数组
for (int i = 1; i <= mid; i++) { // 枚举范围内[1~mid]所有订单
b[s[i]] += d[i]; // 第i个订单因为只会对在s~l之间要借用教室的人产生影响所以可以差分
b[t[i] + 1] -= d[i]; // 差分,注意:是t[i]+1因为要包含t[i]这个点
2 years ago
}
2 years ago
// ② 还原成原数组,sum=a[i],也就是第i天需要借的教室总数
2 years ago
for (int i = 1; i <= n; i++) { // 枚举每一天
2 years ago
sum += b[i]; // 因为b是差分数组所以sum就是在第i天的借教室的总数
if (sum > r[i]) return false; // 如果要借的教室多于空的教室,返回不可行
2 years ago
}
2 years ago
return true; // 返回可行
2 years ago
}
signed main() {
2 years ago
cin >> n >> m; // n:天数m订单数量
for (int i = 1; i <= n; i++) cin >> r[i]; // 第i天可以租借的教室数量
for (int i = 1; i <= m; i++) cin >> d[i] >> s[i] >> t[i]; // 借多少个,从哪天借到哪天
2 years ago
/*
0
check
*/
2 years ago
if (check(m)) { // 如果全部满足
cout << 0 << endl; // 输出0
exit(0); // 直接结束程序
2 years ago
}
2 years ago
/*
使
,
x:
(1)1~xx-1OK
(2)1~x
使
*/
2 years ago
int l = 1, r = m; // 二分左右区间
2 years ago
while (l < r) {
2 years ago
int mid = l + r >> 1;
if (check(mid)) // 如果可行
2 years ago
l = mid + 1; // 增多订单
2 years ago
else // 否则
2 years ago
r = mid; // 减少订单
2 years ago
}
2 years ago
if (l == r) cout << 0 << end;
;
2 years ago
cout << "-1" << endl
2 years ago
<< l; // 输出-1和 第一个不符合条件的订单
2 years ago
}