noip2012 借教室

来源:互联网 发布:网络营销策划ppt范文 编辑:程序博客网 时间:2024/04/29 15:41

描述

在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。

面对海量租借教室的信息,我们自然希望编程解决这个问题。我们需要处理接下来n天的借教室信息,其中第i天学校有ri个教室可供租借。共有m份订单,每份订单用三个正整数描述,分别为dj,sj,tj,表示某租借者需要从第sj天到第tj天租借教室(包括第sj天和第tj天),每天需要租借dj个教室。 
我们假定,租借者对教室的大小、地点没有要求。即对于每份订单,我们只需要每天提供dj个教室,而它们具体是哪些教室,每天是否是相同的教室则不用考虑。

借教室的原则是先到先得,也就是说我们要按照订单的先后顺序依次为每份订单分配教室(这句话很重要,这决定了分配是按照顺序的)。如果在分配的过程中遇到一份订单无法完全满足,则需要停止教室的分配,通知当前申请人修改订单。这里的无法满足指从第sj天到第tj天中有至少一天剩余的教室数量不足dj个。

现在我们需要知道,是否会有订单无法完全满足。如果有,需要通知哪一个申请人修改订单。


program classroom;var n,m,i,s1,l,r,mid,now:longint;    r1,sum:array[1..1000000]of longint;    d,s,t:array[1..1000000]of longint;    flag:boolean;begin read(n,m); for i:=1 to n do read(r1[i]); for i:=1 to m do  read(d[i],s[i],t[i]); l:=1;r:=m+1; //二分终点要注意,如果最后终点不变,直到m+1才不合格,那么借用要求全部满足;如果r改变了,那么要求不满足 now:=0;//如果可行一定是连续的订单,所以可用二分 now指的是上一个mid,为了恢复sum数组 repeat  mid:=(l+r) shr 1;  if mid>now then   begin    for i:=now+1 to mid do     begin      inc(sum[s[i]],d[i]);      dec(sum[t[i]+1],d[i]);  //用到差分     end;   end  else   begin    for i:=mid+1 to now do     begin      dec(sum[s[i]],d[i]);      inc(sum[t[i]+1],d[i]);     end;   end;  now:=mid;  flag:=true;  s1:=0;  for i:=1 to n do //sum[]按照天数计   begin    s1:=s1+sum[i];    if s1>r1[i] then begin flag:=false;break;end;   end;  if flag then   l:=mid+1  else   r:=mid; until l=r;  //表示不满足的位置,所以初始r=m+1 if (flag)and(l=m+1) then  write(0) else  begin   writeln(-1);   write(r);  end;end.


0 0