题目链接:https://www.luogu.com.cn/problem/P1083
题意:给定n天内,每天供应的教室数量ri和m个订单,表示第si到ti天用di个教室。按顺序执行订单,求第一个无法满足的订单编号
看到样例之后大致知道了做法。对于每个订单,把数组r的区间[si,ti]减去di,最后第一个出现某个ri<0时的订单编号就是答案。求第一个无法满足的订单编号,显然可以二分。因为如果前面的满足,那么不满足的一定都在后面;如果当前的已经不满足,那么第一个不满足的一定为在这个编号以及它的前面。由于是先进行一些区间加减,最后再判断是否有某个ri<0,所以可以用差分
#include<bits/stdc++.h> using namespace std; const int N=1e6+10; struct st{int d,s,t;}a[N]; int c[N],r[N],pre[N],n,m,i,f,l,h; bool check(int mid){ memset(pre,0,sizeof(pre)); for (i=1;i<=n;i++) c[i]=r[i]-r[i-1]; for (i=1;i<=mid;i++){ c[a[i].s]-=a[i].d; c[a[i].t+1]+=a[i].d; } for (i=1;i<=n;i++){ pre[i]=pre[i-1]+c[i]; if (pre[i]<0) { //* f=-1; return false; } } return true; } int main(){ scanf("%d%d",&n,&m); for (i=1;i<=n;i++) scanf("%d",&r[i]); for (i=1;i<=m;i++) scanf("%d%d%d",&a[i].d,&a[i].s,&a[i].t); l=0; h=m; f=0; while (h-l>1){ int mid=(l+h)/2; if (check(mid)) l=mid; else h=mid; } printf("%d ",f); if (f==-1) printf("%d",h); return 0; }