【NOIP2017练习】怎样更有力气(二分答案,线性扫描)

题意:OI大师抖儿在夺得银牌之后,顺利保送pku。这一天,抖儿问长者:“我虽然已经保送了,但我的志向是为国家健康工作五十年。请问我应该怎样变得更有力气?”

  长者回答:“你啊,Too Young Too Simple,Sometimes Naive!如果你想要我教你,你要先进行艰苦的修行。”
长者的住宅中有一堵长度为n的墙。每天抖儿起床修行,会选择一段长度为x的区间染成白色。长者的住宅附近有一群香港记者,为了借助抖儿拜访长者,第i天香港记者会将区间[li,ri]染成白色来讨好抖儿(也就是说,每天墙会被抖儿和香港记者各染一次)。现在抖儿已经预先知道了香港记者的动向,他想知道他最少几天就能把墙全部染白,完成修行。
一行一个整数,表示抖儿最少几天能把墙全部染白。
如果m天之后依然无法染白,则输出“Poor Douer!”
对于所有的数据,保证n≤10^18,m≤100000,0<=x≤n且数据随机
思路:lyy出题人系列

 1 var x,y,l,r:array[1..110000]of int64;
 2     m,left,right,last,mid,i:longint;
 3     n,x1:int64;
 4 
 5 procedure swap(var x,y:int64);
 6 var t:int64;
 7 begin
 8  t:=x; x:=y; y:=t;
 9 end;
10 
11 procedure qsort(l,r:longint);
12 var i,j:longint;
13     mid1,mid2:int64;
14 begin
15  i:=l; j:=r; mid1:=x[(l+r)>>1]; mid2:=y[(l+r)>>1];
16  repeat
17   while (mid1>x[i])or((mid1=x[i])and(mid2>y[i])) do inc(i);
18   while (mid1<x[j])or((mid1=x[j])and(mid2<y[j])) do dec(j);
19   if i<=j then
20   begin
21    swap(x[i],x[j]);
22    swap(y[i],y[j]);
23    inc(i); dec(j);
24   end;
25  until i>j;
26  if l<j then qsort(l,j);
27  if i<r then qsort(i,r);
28 end;
29 
30 function max(x,y:int64):int64;
31 begin
32  if x>y then exit(x);
33  exit(y);
34 end;
35 
36 function isok(up:longint):boolean;
37 var t,i:longint;
38     now,len,tmp,ans:int64;
39 
40 begin
41  for i:=1 to up do
42  begin
43   x[i]:=l[i]; y[i]:=r[i];
44  end;
45  t:=up;
46  inc(t); x[t]:=n+1; y[t]:=n+1;
47  qsort(1,t);
48  now:=0; ans:=0;
49  for i:=1 to t do
50  begin
51   if x[i]>now+1 then
52   begin
53    if x1=0 then exit(false);
54    len:=x[i]-now-2;
55    tmp:=len div x1+1;
56    if now+tmp*x1>y[i] then now:=now+tmp*x1;
57    ans:=ans+tmp;
58    if ans>up then exit(false);
59   end;
60   now:=max(now,y[i]);
61  end;
62  exit(true);
63 end;
64 
65 begin
66  assign(input,'liqi.in'); reset(input);
67  assign(output,'liqi.out'); rewrite(output);
68  readln(n,m,x1);
69  for i:=1 to m do read(l[i],r[i]);
70  left:=1; right:=m; last:=m+1;
71  while left<=right do
72  begin
73   mid:=(left+right)>>1;
74   if isok(mid) then begin last:=mid; right:=mid-1; end
75    else left:=mid+1;
76  end;
77  if last=m+1 then writeln('Poor Douer!')
78   else writeln(last);
79  close(input);
80  close(output);
81 end.

【后记】
在你的帮助下,抖儿完成修行的时间是原来的0.01倍。
抖儿对长者说:“我明白了!只有每天坚持锻炼,才能获得力量。”
长者嘿嘿一笑:“你想多了。我只是想让你刷墙而已。”
说完,长者一溜烟地跑了,速度比香港记者还要快好几倍。


原文地址:https://www.cnblogs.com/myx12345/p/7678594.html