|
|
|
@ -134,6 +134,49 @@ int main() {
|
|
|
|
|
|
|
|
|
|
对于为什么可以二分:如果一个人无法被满足,则他后面的人全都不能被满足;如果一个人可以被满足,则他前面的人都可以被满足,这恰恰吻合了我们二分的性质。
|
|
|
|
|
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
using namespace std;
|
|
|
|
|
const int N = 1000010;
|
|
|
|
|
#define int long long
|
|
|
|
|
#define endl "\n"
|
|
|
|
|
int n, m; // 天数和订单的数量
|
|
|
|
|
int r[N]; // 第i天学校有r[i]个教室可借用
|
|
|
|
|
int d[N], s[N], t[N]; // 借的教室数目、从第s天借到t天
|
|
|
|
|
int b[N]; // 差分数组
|
|
|
|
|
bool check(int x) { // 判断能不能通过x个人
|
|
|
|
|
memset(b, 0, sizeof b); // 每次判断都要先初始化差分数组
|
|
|
|
|
int sum = 0; // 记录需要借的教室数
|
|
|
|
|
for (int i = 1; i <= x; i++) {
|
|
|
|
|
b[s[i]] += d[i]; // 因为只会对在s~l之间要借用教室的人产生影响,所以可以差分
|
|
|
|
|
b[t[i] + 1] -= d[i]; // 差分,注意:是t[i]+1,因为要包含t[i]这个点
|
|
|
|
|
}
|
|
|
|
|
for (int i = 1; i <= n; i++) {
|
|
|
|
|
sum += b[i]; // 因为cf是差分数组,所以sum就是在第i天的借教室的总数
|
|
|
|
|
if (sum > r[i]) return false; // 不可行,如果要借的教室多于空的教室
|
|
|
|
|
}
|
|
|
|
|
return true; // 可行
|
|
|
|
|
}
|
|
|
|
|
signed main() {
|
|
|
|
|
cin >> n >> m;
|
|
|
|
|
for (int i = 1; i <= n; i++) cin >> r[i];
|
|
|
|
|
for (int i = 1; i <= m; i++) cin >> d[i] >> s[i] >> t[i];
|
|
|
|
|
if (check(m)) { // 如果全部满足
|
|
|
|
|
cout << 0 << endl; // 输出0
|
|
|
|
|
exit(0); // 直接结束程序
|
|
|
|
|
}
|
|
|
|
|
int l = 1, r = m; // 二分左右区间
|
|
|
|
|
while (l < r) {
|
|
|
|
|
int mid = l + r >> 1;
|
|
|
|
|
if (check(mid)) // 如果可行
|
|
|
|
|
l = mid + 1; // 增多满足人数
|
|
|
|
|
else // 否则
|
|
|
|
|
r = mid; // 减少满足人数
|
|
|
|
|
}
|
|
|
|
|
cout << "-1" << endl
|
|
|
|
|
<< l; // 输出-1和需要修改的人
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### [$P3406$ 海底高铁](https://www.luogu.com.cn/problem/P3406)
|
|
|
|
|

|
|
|
|
|