BZOJ4476 送礼物
2024-09-30 08:20:08
这道题真是有趣呀。
其实就是一个分数规划问题,用一个二分加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 ;
}
最新文章
- delphi FMX 数字下拉滑动
- XMPP客户端开发(1)--连接和登录
- centos PIL 安装
- winform在不同电脑分辨率
- CodeForces 686C-Robbers&#39; watch
- RedHat中敲sh-copy-id命令报错:-bash: ssh-copy-id: command not found
- poj 3317 Stake Your Claim 极大极小搜索
- MD5加密方式
- C#&#160;实现远程控制软件的关键技术
- [jobdu]数组中出现次数超过一半的数字
- JAVA_基础面试题
- Flunetd 用于统一日志记录层的开源数据收集器
- Java调用PDFBox打印自定义纸张PDF
- 程序执行流程/布尔类型与布尔:运算猜数字游戏;库的使用:turtle
- Android7.0适配APK安装
- js字符串方法、数组方法整理
- English trip V1 - B 18. Workplaces 工作地方 Teacher:Russell Key: do / does
- php读取xml中cdata部分方法
- 【Android】Android内存溢出问题---用自行开辟的空间进行对内存管理
- spring-构建mvc工程
热门文章
- js继承的几种方法和es6继承方法
- ajax在同一页面中同控制器不同方法中调用数据并异步刷新的实例
- 【坑】记录一个docker 1.13.1 build 07f3374 版本的坑
- Ubuntu 16.04 swoole扩展安装注意!!!
- laravel构造函数跳转失败
- Python学习手册之控制结构(一)
- [转]Makefile中使用$$的使用
- WPF中的数据模板(DataTemplate)
- 【转】在Ubuntu 16.10 Server 上部署 Moodle
- P1346 电车(dijkstra)