【BZOJ4476&JSOI2015】送礼物(二分,RMQ)

ANS明显是有二分性的

 

二分答案,设二分值为b
M(i,j)−m(i,j)j−i+k>b

显然当l<长度<r时,一端是最小值,一端是最大值。

等于l或r的时候因为可能不满足以上性质,所以RMQ暴力O(nlogn)做。 

a[i]−a[j]>b∗j−b∗i+b∗k 或 a[j]−a[i]>b∗j−b∗i+b∗k
那么
(a[i]+b∗i)−(a[j]+b∗j)>b∗k 或 (−a[i]+b∗i)−(−a[j]+b∗j)>b∗k

 

是一个单调队列的样子

 

  1 var f1,f2:array[1..60000,0..20]of extended;
  2     q:array[1..200000]of longint;
  3     a,e:array[0..200000]of extended;
  4     mi:array[0..30]of int64;
  5     log:array[1..2000000]of longint;
  6     cas,i,v,j:longint;
  7     n,l1,r1,lg:int64;
  8     l,r,mid,k:extended;
  9 
 10 function max(x,y:extended):extended;
 11 begin
 12  if x>y then exit(x);
 13  exit(y);
 14 end;
 15 
 16 function min(x,y:extended):extended;
 17 begin
 18  if x<y then exit(x);
 19  exit(y);
 20 end;
 21 
 22 function querymin(x,y:longint):extended;
 23 var len:longint;
 24 begin
 25  len:=log[y-x+1];
 26  exit(min(f1[x,len],f1[y-mi[len]+1,len]));
 27 end;
 28 
 29 function querymax(x,y:longint):extended;
 30 var len:longint;
 31 begin
 32  len:=log[y-x+1];
 33  exit(max(f2[x,len],f2[y-mi[len]+1,len]));
 34 end;
 35 
 36 procedure build1;
 37 var i,j:longint;
 38 begin
 39  for i:=1 to lg do
 40   for j:=1 to n-mi[i]+1 do f1[j,i]:=min(f1[j,i-1],f1[j+mi[i-1],i-1]);
 41 end;
 42 
 43 procedure build2;
 44 var i,j:longint;
 45 begin
 46  for i:=1 to lg do
 47   for j:=1 to n-mi[i]+1 do f2[j,i]:=max(f2[j,i-1],f2[j+mi[i-1],i-1]);
 48 end;
 49 
 50 function isok(b:extended):boolean;
 51 var h,w,i:longint;
 52 begin
 53  for i:=1 to n do e[i]:=a[i]+b*i;
 54  h:=1; w:=1;
 55  q[1]:=n;
 56  for i:=n-l1+1 downto 1 do
 57  begin
 58   while (h<=w)and(q[h]>i+r1-1) do inc(h);
 59   if e[i]-e[q[h]]>=b*k then exit(true);
 60   while (h<=w)and(e[q[w]]>=e[i+l1-2]) do dec(w);
 61   inc(w); q[w]:=i+l1-2;
 62  end;
 63  for i:=1 to n do e[i]:=-a[i]+b*i;
 64  h:=1; w:=1;
 65  q[1]:=n;
 66  for i:=n-l1+1 downto 1 do
 67  begin
 68   while (h<=w)and(q[h]>i+r1-1) do inc(h);
 69   if e[i]-e[q[h]]>=b*k then exit(true);
 70   while (h<=w)and(e[q[w]]>=e[i+l1-2]) do dec(w);
 71   inc(w); q[w]:=i+l1-2;
 72  end;
 73  exit(false);
 74 end;
 75 
 76 begin
 77  assign(input,'gift.in'); reset(input);
 78  assign(output,'gift.out'); rewrite(output);
 79  readln(cas);
 80  mi[0]:=1;
 81  for i:=1 to 20 do mi[i]:=mi[i-1]*2;
 82  for i:=0 to 19 do
 83   for j:=mi[i] to mi[i+1]-1 do log[j]:=i;
 84  for v:=1 to cas do
 85  begin
 86   readln(n,k,l1,r1);
 87   for i:=1 to n do read(a[i]);
 88   l:=0; r:=1000;
 89   for i:=1 to n do
 90   begin
 91    f1[i,0]:=a[i];
 92    f2[i,0]:=a[i];
 93   end;
 94   lg:=log[r1];
 95   build1; build2;
 96   for i:=1 to n-l1+1 do l:=max(l,(querymax(i,i+l1-1)-querymin(i,i+l1-1))/(l1-1+k));
 97   for i:=1 to n-r1+1 do l:=max(l,(querymax(i,i+r1-1)-querymin(i,i+r1-1))/(r1-1+k));
 98   l1:=l1+1; r1:=r1-1;
 99   if l1<=r1 then
100    while r-l>1e-6 do
101    begin
102     mid:=(r+l)/2;
103     if isok(mid) then l:=mid
104      else r:=mid;
105    end;
106   writeln(l:0:4);
107  end;
108  close(input);
109  close(output);
110 end.

 

posted on 2015-12-03 21:03  myx12345  阅读(594)  评论(0编辑  收藏  举报

导航