题解 [NOIP2012 提高组] 借教室
*题目链接
首先分析是否具有单调性,题目让求哪个租借人最先不能满足要求,显然,让越多人租借,就越容易满足不了需求,具有单调性。可以使用二分答案。
既然是二分答案,考虑如何 \(check\),观察到对于第 \(i\) 名租借者,需要从第 \(s_i\) 天到第 \(t_i\) 天,每天租借 \(d_i\) 间教室,也就是对教室序列执行区间减操作。
由于操作不需要在线,故可以使用差分实现修改。
代码:
const int N=1e6+10;
int n,m;
int r[N],d[N],s[N],t[N];
LL diff[N],sum[N];
int check(int x) {//第x个人
memset(diff,0,sizeof(diff));
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++) {
diff[i]=r[i]-r[i-1];
}
for(int i=1;i<=x;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]<0) return 1;
}
return 0;
}
int main() {
cin>>n>>m;
for(int i=1;i<=n;i++) {
r[i]=read();
}
for(int i=1;i<=m;i++) {
d[i]=read(); s[i]=read(); t[i]=read();
}
int l=1,r=m;
while(l<r) {
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
if(!check(r)) cout<<0;
else cout<<"-1\n"<<r;
return 0;
}