题目链接
解题思路:二分 + 差分
二分每个申请人的编号,如果第 mid 个申请人不需要修改, 那么前面的也一定不需要修改; 如果需要修改,那么后面的不需要考虑。
差分:因为需要同时改变一个区间的值,利用差分数组可以容易求出每天需要的天数
同时本题也可以用线段树维护区间最小值 + 二分来解决;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const int MAX_N = 1e6 + 10;
const int MOD = 1e9 + 7;
const double esp = 1e-9;
int N, M;
int diff[MAX_N], sum[MAX_N], r[MAX_N];
int s[MAX_N], t[MAX_N], d[MAX_N];
bool ask(int m){
memset(diff, 0, sizeof(diff));
memset(sum, 0, sizeof(sum));
for(int i = 1; i <= m; i++){
diff[s[i] ] += d[i];
diff[t[i] + 1 ] -= d[i];
}
for(int i = 1; i <= N; i++){
sum[i] = sum[i - 1] + diff[i];
if(sum[i] > r[i]) return false;
}
return true;
}
void solve(){
scanf("%d%d", &N, &M);
for(int i = 1; i <= N; i++)
scanf("%d", &r[i]);
for(int i = 1; i <= M; i++)
scanf("%d%d%d", &d[i], &s[i], &t[i]);
int l = 1, r = M, res = -1;
if(ask(r)) printf("0\n");
else{
while(r >= l){
int mid = (l + r) / 2;
if(ask(mid)) l = mid + 1;
else{
res = mid;
r = mid - 1;
}
}
if(res == -1) printf("0\n");
else printf("-1\n%d", res);
}
}
int main(){
int TCASE = 1;
// scanf("%d", &TCASE);
while(TCASE--) solve();
return 0;
}