【BZOJ1502】【NOI2005】月下柠檬树
Portal
Solution
显然的是,每一个圆的影子,就是从树上的圆按光线方向平移至地面的圆。至于两个圆之间的连接部分,则是每两个在树上相邻的圆的,对应的影子圆的,公切线围起来的部分,如下图所示

所以我们现在要求每两个在原树上相邻的圆的影子圆构成的图形的并。只看\(x\)轴上半部分,可以把它想象成一个函数,求单点值是\(O(n)\)的,我们不妨用辛普森积分来解决......
相邻圆的公切线和x轴的夹角是可以求出来的,然后就能解出公切线的解析式,以及有效范围。注意这些东西要预处理!千万不要放在求值函数里面。\(EPS\)大约设置到\(10^{-7}\)才不会出错,效率也相对比较高。
Code
#include <cstdio>
#include <cmath>
using namespace std;
const int N=505;
const double EPS=1e-7,INF=1e10,PI=3.14159265358979323846;
int n,sum;
double alpha,h[N],p[N],r[N];
double k[N],b[N],lx[N],rx[N];
bool exist[N];
inline double max(double x,double y){return x>y?x:y;}
inline double min(double x,double y){return x<y?x:y;}
inline void swap(int &x,int &y){x^=y^=x^=y;}
inline bool in(int a,int b){
if(r[a]>r[b]) swap(a,b);
return p[a]+r[a]-EPS<=p[b]+r[b]&&p[a]-r[a]+EPS>=p[b]-r[b];
}
double calc(int a,int b,double &k,double &bb,double &xl,double &xr){
if(p[a]>p[b]) swap(a,b);
double beta=asin((r[b]-r[a])/(p[b]-p[a]));
k=tan(beta);
double tx;
if(r[a]>=r[b]){
beta=-beta;
tx=p[b]+r[b]/sin(beta);
bb=-k*tx;
xr=tx-(cos(beta)*(r[b]/tan(beta)));
xl=tx-(cos(beta)*(r[a]/tan(beta)));
}
else{
tx=p[a]-r[a]/sin(beta);
bb=-k*tx;
xl=tx+(cos(beta)*(r[a]/tan(beta)));
xr=tx+(cos(beta)*(r[b]/tan(beta)));
}
}
double f(double x){
double res=0;
for(int i=1;i<=n;i++)
if(fabs(x-p[i])<=r[i])
res=max(res,sqrt(r[i]*r[i]-fabs(x-p[i])*fabs(x-p[i])));
for(int i=1;i<n;i++)
if(exist[i])
if(lx[i]<=x+EPS&&x-EPS<=rx[i])
res=max(res,k[i]*x+b[i]);
return res;
}
double simpson(double l,double r){
double mid=(l+r)*0.5;
return (f(l)+4*f(mid)+f(r))*(r-l)/6;
}
double solve(double l,double r){
double mid=(l+r)/2,lmid=(l+mid)/2,rmid=(mid+r)/2;
double val=simpson(l,r);
if(fabs(val-(simpson(l,mid)+simpson(mid,r)))<EPS) return val;
return solve(l,mid)+solve(mid,r);
}
int main(){
scanf("%d%lf",&n,&alpha);
n++;
for(int i=1;i<=n;i++){
scanf("%lf",h+i);
h[i]+=h[i-1];
p[i]=h[i]/tan(alpha);
}
for(int i=1;i<n;i++) scanf("%lf",r+i);
double xl=INF,xr=-INF;
for(int i=1;i<=n;i++){
xl=min(xl,p[i]-r[i]);
xr=max(xr,p[i]+r[i]);
}
for(int i=1;i<n;i++){
exist[i]=!in(i,i+1);
if(exist[i])
calc(i,i+1,k[i],b[i],lx[i],rx[i]);
}
printf("%.2lf\n",solve(xl,xr)*2);
return 0;
}
【BZOJ1502】【NOI2005】月下柠檬树的更多相关文章
- BZOJ1502: [NOI2005]月下柠檬树
Simpson法相当好用啊!神奇的骗分算法! /************************************************************** Problem: 1502 ...
- [日常摸鱼]bzoj1502[NOI2005]月下柠檬树-简单几何+Simpson法
关于自适应Simpson法的介绍可以去看我的另一篇blog http://www.lydsy.com/JudgeOnline/problem.php?id=1502 题意:空间里圆心在同一直线上且底面 ...
- 【BZOJ1502】[NOI2005]月下柠檬树 Simpson积分
[BZOJ1502][NOI2005]月下柠檬树 Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树 ...
- BZOJ 1502: [NOI2005]月下柠檬树 [辛普森积分 解析几何 圆]
1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1070 Solved: 596[Submit][Status] ...
- 【BZOJ-1502】月下柠檬树 计算几何 + 自适应Simpson积分
1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1017 Solved: 562[Submit][Status] ...
- [NOI2005]月下柠檬树[计算几何(simpson)]
1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1169 Solved: 626[Submit][Status] ...
- [NOI2005]月下柠檬树
题意 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser autoint Logout 捐赠本站 Probl ...
- 5.21 省选模拟赛 luogu P4207 [NOI2005]月下柠檬树 解析几何 自适应辛普森积分法
LINK:月下柠檬树 之前感觉这道题很鬼畜 实际上 也就想到辛普森积分后就很好做了. 辛普森积分法的式子不再赘述 网上多的是.值得一提的是 这道题利用辛普森积分法的话就是一个解析几何的问题 而并非计算 ...
- 【bzoj1502】[NOI2005]月下柠檬树 自适应Simpson积分
题目描述 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思索着人生的哲理.李哲是一个喜爱思考的孩子,当他看到在月 ...
- BZOJ1502:[NOI2005]月下柠檬树——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1502 https://www.luogu.org/problemnew/show/P4207 李哲 ...
随机推荐
- 关于spring boot 使用 mybatis plus INSERT的时候id报错
mybatis plus 在INSERT的时候会默认自动设置插入id 我当时数据库采用的id自增. 在使用插入语句的时候并没有set ID 但是它默认给了一大串 更改mybatis plus全局配置 ...
- 通过spark-submit提交hadoop配置的方法
通过spark提交的spark开头的配置在程序启动后会添加到SparkConf中,但是hadoop相关的配置非spark开头会被过滤掉,但是只要在这些配置的key前面添加spark.hadoop.前缀 ...
- 【LDAP安装】在已编译安装的PHP环境下安装LDAP模块
在已编译安装的PHP环境下安装LDAP模块 (乐维温馨提示:其他模块也能以这个方式安装) 1.在PHP源码包内找到ldap模块文件 cd php-5.6.37 cd ext/ldap/ 2.phpiz ...
- printf命令详解
基础命令学习目录首页 本文是Linux Shell系列教程的第(八)篇,更多shell教程请看:Linux Shell系列教程 在上一篇:Linux Shell系列教程之(七)Shell输出这篇文章中 ...
- python清空列表的方法
1.大数据量的list,要进行局部元素删除,尽量避免用del随机删除,非常影响性能,如果删除量很大,不如直接新建list,然后用下面的方法释放清空旧list. 2.对于一般性数据量超大的list,快速 ...
- 兼容所有浏览器的旋转效果-IE滤镜Matrix和CSS3transform
在现代浏览器中使用CSS3的transform样式即可轻松搞定,但是对于国内IE浏览器(特别是7,8)还占有较大份额的情况下,兼容性还是必须要考虑的,所以也特意记录下IE旋转滤镜的使用. 在IE下的旋 ...
- 王者荣耀交流协会互评Beta版本及答复功能改进建议、Bug修正
互评Beta版本 欢迎来怼团队博客园安卓APP Thunder团队爱阅app 探路者团队贪吃蛇 Hello World!团队项目空天猎 答复功能改进建议 答复其他各组给出的“就现有技术和工作量,不改变 ...
- 2-Third Scrum Meeting-20151203
任务安排 闫昊: 今日完成:请假.(编译+计组,压力有点大) 明日任务:设计本地数据库. 唐彬: 今日完成:请假.(编译+计组,压力有点大) 明日任务:阅读ios客户端代码. 史烨轩: 今日完成:请假 ...
- Daily Scrumming 2015.10.20(Day 1)
一.今明两天任务表 Member Today’s Task Tomorrow’s Task 江昊 购买服务器,搭建服务器,配置服务器端用户与权限管理 配置ruby与rails环境 配置mysql与数据 ...
- OO第三阶段作业总结
调研: 最早的程序设计是直接采用机器语言来编写的,或者使用二进制码来表示机器能够识别和执行的指令和数据.机器语言的优点在于速度快,缺点在于写起来实在是太困难了,编程效率低,可读性差,并且 ...