P1083 借教室(差分前缀和&二分)
思路:差分前缀和+二分。对于区间的加减可以用通过差分数组实现,因为要求最小不满足条件的编号,因为此情况具有单调性,所以可以二分答案。
时间复杂度:
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
struct p{
int d,l,r;
}a[N];
int n,m,b[N];
ll dif[N];
bool jg(int x){
memset(dif,0,sizeof dif);
for(int i=1;i<=x;i++)
dif[a[i].l]+=a[i].d,dif[a[i].r+1]-=a[i].d;//差分数组
for(int i=1;i<=n;i++){
dif[i]+=dif[i-1];//前缀和.
if(dif[i]>b[i]) return 0;
}
return 1;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].d,&a[i].l,&a[i].r);
if(jg(m)) return puts("0"),0;
int l=1,r=m;
while(l<r){
int mid=(l+r)>>1;
if(jg(mid)) l=mid+1;
else r=mid;//因为是最大出现的不满足的所以r=mid,而不是r=mid-1(这样是找满足条件的最大的)
}
printf("-1\n%d\n",r);
return 0;
}