题意:n天,每天有ai个教室可以租借,一共有m条订单,从第l天到第r天需要租借w间教室,问是否能满足这m条订单,能满足就输出0,不能满足输出两行:第一行-1,第二行输出是第一个无法满足的订单。
思路:考虑l~r区间修改使用差分,难点在查找第一个无法满足的订单是在哪,考虑二分答案,算是一个很巧妙的二分答案(我一开始也没想到)。
AC代码:
#include<bits/stdc++.h>
#define js ios::sync_with_stdio(false)
#define ll long long
using namespace std;
const ll N=2e6+5;
const ll INF=0x3f3f3f;
long long a[N],d[N],s[N],t[N],c[N];
int n,m;
bool check(int mid){//mid作为查找第几个订单
memset(c,0,sizeof c);
for(int i=1;i<=n;i++){
c[i]=a[i]-a[i-1];//差分
}
for(int i=1;i<=mid;i++){
c[s[i]]-=d[i];
c[t[i]+1]+=d[i];//差分模板
}
for(int i=1;i<=n;i++){
c[i]+=c[i-1];
if(c[i]<0){
return false;
}
}
return true ;
}
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
cin>>d[i]>>s[i]>>t[i];
}
int l=0,r=m,mid,ans=0;
while(l<r){//二分模板
mid=(l+r)/2;
if(check(mid)){
l=mid+1;
}
else{
ans=mid;
r=mid;
}
}
if(!ans){
cout<<"0\n";
}
else cout<<"-1\n"<<ans<<endl;
}
int main(){
js;
solve();
return 0;
}