【BZOJ4476&JSOI2015】送礼物(二分,RMQ)
2015-12-03 21:03
603 查看
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
是一个单调队列的样子
var f1,f2:array[1..60000,0..20]of extended; q:array[1..200000]of longint; a,e:array[0..200000]of extended; mi:array[0..30]of int64; log:array[1..2000000]of longint; cas,i,v,j:longint; n,l1,r1,lg:int64; l,r,mid,k:extended; function max(x,y:extended):extended; begin if x>y then exit(x); exit(y); end; function min(x,y:extended):extended; begin if x<y then exit(x); exit(y); end; function querymin(x,y:longint):extended; var len:longint; begin len:=log[y-x+1]; exit(min(f1[x,len],f1[y-mi[len]+1,len])); end; function querymax(x,y:longint):extended; var len:longint; begin len:=log[y-x+1]; exit(max(f2[x,len],f2[y-mi[len]+1,len])); end; procedure build1; var i,j:longint; begin for i:=1 to lg do for j:=1 to n-mi[i]+1 do f1[j,i]:=min(f1[j,i-1],f1[j+mi[i-1],i-1]); end; procedure build2; var i,j:longint; begin for i:=1 to lg do for j:=1 to n-mi[i]+1 do f2[j,i]:=max(f2[j,i-1],f2[j+mi[i-1],i-1]); end; function isok(b:extended):boolean; var h,w,i:longint; begin for i:=1 to n do e[i]:=a[i]+b*i; h:=1; w:=1; q[1]:=n; for i:=n-l1+1 downto 1 do begin while (h<=w)and(q[h]>i+r1-1) do inc(h); if e[i]-e[q[h]]>=b*k then exit(true); while (h<=w)and(e[q[w]]>=e[i+l1-2]) do dec(w); inc(w); q[w]:=i+l1-2; end; for i:=1 to n do e[i]:=-a[i]+b*i; h:=1; w:=1; q[1]:=n; for i:=n-l1+1 downto 1 do begin while (h<=w)and(q[h]>i+r1-1) do inc(h); if e[i]-e[q[h]]>=b*k then exit(true); while (h<=w)and(e[q[w]]>=e[i+l1-2]) do dec(w); inc(w); q[w]:=i+l1-2; end; exit(false); end; begin assign(input,'gift.in'); reset(input); assign(output,'gift.out'); rewrite(output); readln(cas); mi[0]:=1; for i:=1 to 20 do mi[i]:=mi[i-1]*2; for i:=0 to 19 do for j:=mi[i] to mi[i+1]-1 do log[j]:=i; for v:=1 to cas do begin readln(n,k,l1,r1); for i:=1 to n do read(a[i]); l:=0; r:=1000; for i:=1 to n do begin f1[i,0]:=a[i]; f2[i,0]:=a[i]; end; lg:=log[r1]; build1; build2; for i:=1 to n-l1+1 do l:=max(l,(querymax(i,i+l1-1)-querymin(i,i+l1-1))/(l1-1+k)); for i:=1 to n-r1+1 do l:=max(l,(querymax(i,i+r1-1)-querymin(i,i+r1-1))/(r1-1+k)); l1:=l1+1; r1:=r1-1; if l1<=r1 then while r-l>1e-6 do begin mid:=(r+l)/2; if isok(mid) then l:=mid else r:=mid; end; writeln(l:0:4); end; close(input); close(output); end.
相关文章推荐
- web前台工作笔记(时间戳、js中clone的使用、js中动态填充数据注意事项、前台查错方法的学习)
- js高级篇1之prototype原型对象的应用
- 0707什么是JSON+如何处理JSON字符串0
- js倒计时
- 全选和地区联动
- IE兼容模式下两个小问题,JSON.stringify和SCRIPT70 无权限
- Eclipse使用总结——修改(My)Eclipse默认的Servlet和jsp代码模板
- jsp页面中frameset的使用方法
- jstorm安装
- 同步刷新时对菜单格式的js点击增加class
- 在js中如何比较两个时间字符串的大小
- jsp导出Excel或者Word及一个form表单中出现多个按钮提交不同的内容
- jsp学习笔记
- D3.js -- 图片制作
- BZOJ 1012 [JSOI2008] 最大数 maxnumber 题解&代码
- javascript字符串单引号与双引号的区别
- 轻松学习JavaScript十:JavaScript的Date对象制作一个简易钟表
- js格式校验
- Gradle 编译时选择不同的 google-services.json
- JS 获取鼠标所点击表格中的某行某列的值