【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.
null