[JZOJ4640] 【GDOI2017模拟7.15】妖怪
题目
描述
题目大意
给你一堆aia_iai和bib_ibi(方便起见用的变量和上面不一样),让你搞出一个xxx(相当于题目中的ba\frac{b}{a}ab,随便推推就能知道),
使得maxai+bi+aix+bix\max a_i+b_i+a_ix+\frac{b_i}{x}maxai+bi+aix+xbi最小。
思考历程
第一眼看下去,最大最小放一起,显然就是一个二分啊!
然后开始想……想不出来,推了个式子,感觉似乎要三分套三分套三分……
更气的是这题还不好打暴力。
所以推了很久之后什么都没有打。
正解
其实这个题目的正解有好几种。
先说二分的做法(WMY大佬的方法,只可惜被卡了常数):
首先我们二分答案,然后判断是否可行。
要满足ai+bi+aix+bix≤ansa_i+b_i+a_ix+\frac{b_i}{x}\leq ansai+bi+aix+xbi≤ans,
变化一下式子:aix2+(ai+bi−ans)x+bi≤0a_ix^2+(a_i+b_i-ans)x+b_i\leq 0aix2+(ai+bi−ans)x+bi≤0
发现可以用一元二次方程的方法来解,
于是对于每个aia_iai和bib_ibi,我们都可以得出一个解集。
然后取它们的交集,如果不为空就成立。
正确性显然。
再说三分的做法:
首先有个重要的结论:y=ai+bi+aix+bixy=a_i+b_i+a_ix+\frac{b_i}{x}y=ai+bi+aix+xbi的图像是一个单峰函数(VVV字形,左边陡,右边缓)。
LYL给出了一个很强的证明:
首先ai+bia_i+b_iai+bi是定值,先不理它,只考虑y=aix+bixy=a_ix+\frac{b_i}{x}y=aix+xbi
变化式子:aix2−yx+bi=0a_ix^2-yx+b_i=0aix2−yx+bi=0
一元二次方程!然后算出Δ=y2−4aibi\Delta=y^2-4a_ib_iΔ=y2−4aibi,解为x=y±y2−4aibi2ax=\frac{y \pm\sqrt{y^2-4a_ib_i}}{2a}x=2ay±y2−4aibi
这时候就可以脑补出它的图像了……
显然,方程的解只有一个的时候就是顶点,所以顶点为(aba,2ab)(\frac{\sqrt{ab}}{a},2\sqrt{ab})(aab,2ab)
还有YMQ的证明:
将yyy除以aia_iai,设ci=biaic_i=\frac{b_i}{a_i}ci=aibi,则y=x+cixy=x+\frac{c_i}{x}y=x+xci
这就相当于反比例函数上的纵坐标和横坐标之和!
显然在直线y=xy=xy=x上最优……(具体证明可以用基本不等式)
整理一下,当x=abax=\frac{\sqrt{ab}}{a}x=aab时最优。
证明完了,下面是做法:
对于每个iii,都会有一个图象。将它们放在一起,取maxmaxmax,可以发现图象是单峰(谷)的。
考虑反证,如果图象为WWW形,那么中间交接的那个地方实际上可以继续延伸,在上面更高的地方形成VVV形,所以不可能会出现WWW形。
所以三分出最低点就可以了。
还有一种方法是最优秀的线性方法。
考虑斜率优化。
假设ai<aja_i<a_jai<aj且yi<yjy_i<y_jyi<yj,那么ai+bi+aix+bix<aj+bj+ajx+bjxa_i+b_i+a_ix+\frac{b_i}{x}<a_j+b_j+a_jx+\frac{b_j}{x}ai+bi+aix+xbi<aj+bj+ajx+xbj
变化式子:T(i,j)=−bi−bjai−aj<xT(i,j)=-\frac{b_i-b_j}{a_i-a_j}<xT(i,j)=−ai−ajbi−bj<x(TTT只是为了后面方便表示)
然后就可以斜率优化了!
先处理出一个斜率递增的序列,对于序列上的每个点iii,在x∈[T(i−1,i),T(i,i+1)]x\in [T(i-1,i),T(i,i+1)]x∈[T(i−1,i),T(i,i+1)]时,yiy_iyi是最大的。
所以求出xxx在这个区间内yiy_iyi的最小值就好了。
将yiy_iyi的VVV形图象画出来,就可以发现这个区间的位置及对应的最小值的情况。
在顶点左边,跨过顶点,在顶点右边三种情况分类讨论。
这就可以O(1)O(1)O(1)求出它的最小值。
总的来说,这个方法是线性的。
代码
线性做法(我只打了线性的)
using namespace std;
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
inline int input(){char ch=getchar();while (ch<'0' || '9'<ch)ch=getchar();int x=0;do{x=x*10+ch-'0';ch=getchar();}while ('0'<=ch && ch<='9');return x;
}
#define N 1000010
int n;
struct Monster{int a,b;
} d[N];
inline bool cmpd(const Monster &x,const Monster &y){return x.a<y.a || x.a==y.a && x.b>y.b;
}
int q[N],head,tail;
inline bool pd(int i,int j,int k){return -(long long)(d[i].b-d[j].b)*(d[j].a-d[k].a)>=-(long long)(d[j].b-d[k].b)*(d[i].a-d[j].a);
}
inline double calc(int i,int j){return -(double)(d[i].b-d[j].b)/(d[i].a-d[j].a);
}
inline double get(int k,double l,double r){if (l-r>1e-8)return 1e8;double mn=sqrt(1ll*d[k].a*d[k].b)/d[k].a;if (r<mn)return d[k].a+d[k].b+d[k].a*r+d[k].b/r;if (l>mn)return d[k].a+d[k].b+d[k].a*l+d[k].b/l;return d[k].a+d[k].b+d[k].a*mn+d[k].b/mn;
}
int main(){n=input();for (int i=1;i<=n;++i)d[i]={input(),input()};sort(d+1,d+n+1,cmpd);for (int i=1;i<=n;++i){while (head<tail && pd(q[tail-1],q[tail],i))tail--;q[++tail]=i;}double ans=get(q[1],1e-4,calc(q[1],q[2]));for (int i=2;i<tail;++i)ans=min(ans,get(q[i],calc(q[i-1],q[i]),calc(q[i],q[i+1])));ans=min(ans,get(q[tail],calc(q[tail-1],q[tail]),1e8));printf("%.4lf",ans);return 0;
}
自认为讲解得比较清晰,就不打注释了。
总结
面对这样有关式子和最值的题目,二分和三分都是很好的思考方向。
有时候还可以尝试一下斜率优化。
最后我们认识了这样的函数y=ax+bxy=ax+\frac{b}{x}y=ax+xb,它的顶点在(aba,2ab)(\frac{\sqrt{ab}}{a},2\sqrt{ab})(aab,2ab)
转载于:https://www.cnblogs.com/jz-597/p/11145220.html
[JZOJ4640] 【GDOI2017模拟7.15】妖怪相关推荐
- jzoj4640. 【GDOI2017模拟7.15】妖怪
Description Input Output Sample Input 3 1 1 1 2 2 2 Sample Output 8.0000 Data Constraint 题解 我还挺喜欢数学的 ...
- 【折半搜索-经典题目】中山纪念中学暑期游Day13——【GDOI2017模拟8.15】Buy
前言 考试时有道题目用到了[折半搜索] 老师推荐了这道经典题目让大家练习[前后部分算法不同]的题目 虽然不知道我有没有时间做,好歹先把题目记录一下,免得以后找不到了qwq 题目 Input Outpu ...
- [双指针|模拟] leetcode 15 三数之和
[双指针|模拟] leetcode 15 三数之和 1.题目 题目链接 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ? ...
- jzoj 5906. 【NOIP2018模拟10.15】传送门(树形dp)
5906. [NOIP2018模拟10.15]传送门 Description 8102年,Normalgod在GLaDOS的帮助下,研制出了传送枪.但GLaDOS想把传送枪据为己有,于是把Normal ...
- 2020.03.11模拟赛15(第一题)
1.水果盛宴(fruit) 题目描述 贝茜又再一次地闯入了 Farmer John 的房子!她在厨房发现了一堆柠檬和一堆橘子(每堆都有无限多个),并且,她希望尽可能地多吃. 贝茜的有一个饱腹值上限 T ...
- jzoj5904. 【NOIP2018模拟10.15】刺客信条(并查集)
5904. [NOIP2018模拟10.15]刺客信条 Description 故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一 ...
- JZOJ 5977. 【清华2019冬令营模拟12.15】堆
Description Input Output Sample Input 10 10 0 1 1 2 2 4 3 12 2 6 2 15 3 5 3 10 7 7 9 16 2 3 1 10 9 2 ...
- JZOJ 3775. 【NOIP2014模拟8.15】因子的排列
Description 一天,小B学习了分解质因数的相关内容.他发现,一个数的质因子可以有许多不同的排列方式,例如20=2*2*5=2*5*2=5*2*2,那么小B认为20的质因子有3种不同的排列方式 ...
- NOIP模拟测试15「建造城市city(插板法)·轰炸·石头剪刀布」
建造城市 题解 先思考一个简单问题 10个$toot$ 放进5间房屋,每个房屋至少有1个$toot$,方案数 思考:插板法,$10$个$toot$有$9$个缝隙,$5$间房屋转化为$4$个挡板,放在t ...
- jzoj3771. 【NOI2015模拟8.15】小 Z 的烦恼
Description 小 Z 最近遇上了大麻烦,他的数学分析挂科了.于是他只好找数分老师求情. 善良的数分老师答应不挂他,但是要求小 Z 帮助他一起解决一个难题问题是这样的,现在有 n 个标号为 1 ...
最新文章
- oracle列字符可以增加长度,ORACLE字符列长度语义
- Serverless Kubernetes 容器服务介绍
- Python中有几种办法交换两个变量的值?
- 四、爬虫中的urllib库使用
- 多路 IO 转接 :epoll 函数
- mysql 协议的query包及解析
- mysql blob key length_mysql提示used in key specification without a key length
- 尽可能地做到无服务器,但不止于此
- oracle唯一索引能删除吗,Oracle:ora-02429:无法用于删除强制唯一/主键的索引 解决...
- 计算机专业英语课后答案北京理工大学,计算机专业英语
- Google docs支持上传任何文档包括pdf...Cool!
- 惠普打印机故障代码_惠普激光打印机故障代码
- Linux i2c-tools使用及调试
- 两种方法求x的n次幂
- matlab corner 舍弃,成长就是不断地丢弃与拾取 — 读The Glass Castle《玻璃城堡》有感...
- redis之集群运维总结
- Unreal Engine 4 渲染目标(Render Target)教程 之 实现雪地足迹(下)
- C++ 之 for 循环 | C++11 for 循环 | 内存 Destory 示例
- shell脚本 sh shebang “#!/bin/sh“
- dblink(dblink是什么意思)
热门文章
- Bagging与Boosting的区别与联系
- Linux怎么登录redis数据库,Linux 系统上 Redis 数据库的 安装 部署 使用
- 微信小程序云开发教程-云函数入门(2)-接收参数、前端调用
- 记飞机大战小游戏1.0
- linux赋权限2770,Linux权限:SUID,SGID以及粘滞位
- linux之VMware安装Centos7
- 二十五、JAVA多线程(二、吃苹果案例)
- spring简易学习笔记三(AOP)
- Win 10 下载与安装 Oracle 12c 详细图解 与 Oracle 12c 卸载
- Linux 网络命令 ip、ifconfig