这道题真是有趣呀。

其实就是一个分数规划问题,用一个二分加log来得去掉分母。

分四种情况讨论

1.lenth > L && num ( max ) > num ( min )

2.lenth > L && num ( max ) < num ( min )

3.lenth == L && num ( max ) > num ( min )

4.lenth == L && num ( max ) < num ( min )

1,2种情况中最大值与最小值一定在选择序列两端,设左右端点编号为i,j

1. ( Vi - Vj ) / ( i - j + k ) = ans -> ( Vi - i * ans ) - ( Vj - j * ans ) = k * ans

二分ans并check左式最大值是否大于右式

2.( Vj - Vi ) / ( i - j + k ) = ans -> ( Vj + j * ans ) - ( Vi + i * ans ) = k * ans

同情况1

3,4用单调队列for一遍就可以了

 #include<cstdio>
#include<algorithm>
#include<cassert>
//#define DEBUG
using namespace std ; const int MAXN = * + ;
int N , K , L , R ;
long long a [ MAXN ] ;
int p [ MAXN ] ; template < class T1 , class T2 >
void max_equal ( T1 & a , const T2 & b ) {
if ( a < b ) a = b ;
} double solve1 ( const double M ) {
#define f(i) (a[i]-M*(i))
double ans = -1e9 ;
int l = , r = - ;
for ( int i = L ; i <= N ; ++ i ) {
while ( r - l + >= && i - p [ l ] + > R ) ++ l ;
while ( r - l + >= && ! ( f ( p [ r ] ) < f ( i - L + ) ) ) -- r ;
p [ ++ r ] = i - L + ;
max_equal ( ans , f ( i ) - f ( p [ l ] ) ) ;
}
return ans ;
#undef f
} double Solve1 () {
double L = , R = 1e4 ;
while ( R - L >= 1e- ) {
const double M = ( L + R ) / ;
if ( solve1 ( M ) >= K * M ) L = M ;
else R = M ;
}
return ( L + R ) / ;
} double solve2 ( const double M ) {
#define f(i) (a[i]+M*(i))
double ans = -1e9 ;
int l = , r = - ;
for ( int i = L ; i <= N ; ++ i ) {
while ( r - l + >= && i - p [ l ] + > R ) ++ l ;
while ( r - l + >= && ! ( f ( p [ r ] ) > f ( i - L + ) ) ) -- r ;
p [ ++ r ] = i - L + ;
max_equal ( ans , f ( p [ l ] ) - f ( i ) ) ;
}
return ans ;
#undef f
} double Solve2 () {
double L = , R = 1e4 ;
while ( R - L >= 1e- ) {
const double M = ( L + R ) / ;
if ( solve2 ( M ) >= K * M ) L = M ;
else R = M ;
}
return ( L + R ) / ;
} double Solve3 () {
double ans = -1e9;
int l = , r = - ;
for ( int i = ; i <= N ; ++ i ) {
while ( r - l + >= && i - p [ l ] + > L ) ++ l ;
while ( r - l + >= && ! ( a [ p [ r ] ] < a [ i ] ) ) -- r ;
p [ ++ r ] = i ;
max_equal ( ans , a [ i ] - a [ p [ l ] ] ) ;
}
return ans / ( L - + K ) ;
} double Solve4 () {
double ans = -1e9;
int l = , r = - ;
for ( int i = ; i <= N ; ++ i ) {
while ( r - l + >= && i - p [ l ] + > L ) ++ l ;
while ( r - l + >= && ! ( a [ p [ r ] ] > a [ i ] ) ) -- r ;
p [ ++ r ] = i ;
max_equal ( ans , a [ p [ l ] ] - a [ i ] ) ;
}
return ans / ( L - + K ) ;
} double solve () {
scanf ( "%d%d%d%d" , & N , & K , & L , & R ) ;
for ( int i = ; i <= N ; ++ i ) scanf ( "%lld" , & a [ i ] ) ;
return max ( max ( Solve1 () , Solve2 () ) , max ( Solve3 () , Solve4 () ) ) ;
} int main () {
int T ;
scanf ( "%d" , & T ) ;
while ( T -- ) printf ( "%.4lf\n" , solve () ) ;
return ;
}

最新文章

  1. delphi FMX 数字下拉滑动
  2. XMPP客户端开发(1)--连接和登录
  3. centos PIL 安装
  4. winform在不同电脑分辨率
  5. CodeForces 686C-Robbers&#39; watch
  6. RedHat中敲sh-copy-id命令报错:-bash: ssh-copy-id: command not found
  7. poj 3317 Stake Your Claim 极大极小搜索
  8. MD5加密方式
  9. C#&#160;实现远程控制软件的关键技术
  10. [jobdu]数组中出现次数超过一半的数字
  11. JAVA_基础面试题
  12. Flunetd 用于统一日志记录层的开源数据收集器
  13. Java调用PDFBox打印自定义纸张PDF
  14. 程序执行流程/布尔类型与布尔:运算猜数字游戏;库的使用:turtle
  15. Android7.0适配APK安装
  16. js字符串方法、数组方法整理
  17. English trip V1 - B 18. Workplaces 工作地方 Teacher:Russell Key: do / does
  18. php读取xml中cdata部分方法
  19. 【Android】Android内存溢出问题---用自行开辟的空间进行对内存管理
  20. spring-构建mvc工程

热门文章

  1. js继承的几种方法和es6继承方法
  2. ajax在同一页面中同控制器不同方法中调用数据并异步刷新的实例
  3. 【坑】记录一个docker 1.13.1 build 07f3374 版本的坑
  4. Ubuntu 16.04 swoole扩展安装注意!!!
  5. laravel构造函数跳转失败
  6. Python学习手册之控制结构(一)
  7. [转]Makefile中使用$$的使用
  8. WPF中的数据模板(DataTemplate)
  9. 【转】在Ubuntu 16.10 Server 上部署 Moodle
  10. P1346 电车(dijkstra)