bzoj2402 陶陶的难题II
这个是题目描述:

题解:
啊啊啊啊啊……
垃圾分数规划。
垃圾树链剖分。
垃圾斜率优化。
垃圾darkbzoj。
这里才是题解:
我们设那个分数的值=k,那么有
$(yi-k*xi)+(qj-k*pj)=0$
我们要做的是让k最大。
那么很明显开两颗线段树,每个节点存一个凸包。
鉴于我们要让b值最大,我们要维护一个上凸包。
然后就是三分凸包+树剖。
代码:
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 30050
#define db double
int n,hed[N],cnt,m;
const db inf = 1e10;
const db eps = 1e-;
struct Pnt
{
db x,y;
}p1[N],p2[N];
struct EG
{
int to,nxt;
}e[*N];
void ae(int f,int t)
{
e[++cnt].to = t;
e[cnt].nxt = hed[f];
hed[f] = cnt;
}
int fa[N],siz[N],son[N],dep[N],top[N];
int tin[N],tim;
void dfs1(int u,int f)
{
siz[u]=;
fa[u]=f;
dep[u]=dep[f]+;
for(int j=hed[u];j;j=e[j].nxt)
{
int to = e[j].to;
if(to==f)continue;
dfs1(to,u);
siz[u]+=siz[to];
if(siz[to]>siz[son[u]])son[u]=to;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;
tin[u]=++tim;
if(son[u])
{
dfs2(son[u],tp);
for(int j=hed[u];j;j=e[j].nxt)
{
int to = e[j].to;
if(to==fa[u]||to==son[u])continue;
dfs2(to,to);
}
}
}
struct Pair
{
db x,y;int id;
Pair(){}
Pair(db x,db y,int i):x(x),y(y),id(i){}
friend bool operator < (Pair a,Pair b)
{
if(fabs(a.x-b.x)<eps)return a.y<b.y;
return a.x<b.x;
}
};
struct segtree
{
db x[N],y[N];
Pair tmp[N];
int a[*N],ens[N<<],beg[N<<],tm;
int ct,s[N];
segtree(){tm=;}
void build(int l,int r,int u)
{
ct = ;
for(int i=l;i<=r;i++)tmp[i] = Pair(x[i],y[i],i);
sort(tmp+l,tmp++r);
for(int i=l;i<=r;i++)
{
while(ct>=&&(tmp[i].y-y[s[ct]])*(x[s[ct]]-x[s[ct-]])>(y[s[ct]]-y[s[ct-]])*(tmp[i].x-x[s[ct]]))
ct--;
s[++ct]=tmp[i].id;
}
beg[u]=tm+;
for(int i=;i<=ct;i++)a[++tm]=s[i];
ens[u]=tm;
if(l==r)return ;
int mid = (l+r)>>;
build(l,mid,u<<);
build(mid+,r,u<<|);
}
int ret;
void div_3(int u,db k)
{
int l = beg[u],r = ens[u];
while(r-l>)
{
int lm = (l+l+r)/,rm = (l+r+r)/;
if(y[a[lm]]-k*x[a[lm]]>y[a[rm]]-k*x[a[rm]])r=rm;
else l=lm;
}
for(int i=l;i<=r;i++)
if(y[a[i]]-k*x[a[i]]>y[ret]-k*x[ret])ret=a[i];
}
void query(int l,int r,int u,int ql,int qr,db k)
{
if(l==ql&&r==qr)
{
div_3(u,k);
return ;
}
int mid = (l+r)>>;
if(qr<=mid)query(l,mid,u<<,ql,qr,k);
else if(ql>mid)query(mid+,r,u<<|,ql,qr,k);
else query(l,mid,u<<,ql,mid,k),query(mid+,r,u<<|,mid+,qr,k);
}
int get_ret(int x,int y,db k)
{
ret = tin[x];
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
query(,n,,tin[top[x]],tin[x],k);
x = fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
query(,n,,tin[x],tin[y],k);
return ret;
}
}tr[];
db gt(int x,int y,db k)
{
int a = tr[].get_ret(x,y,k);
int b = tr[].get_ret(x,y,k);
return (tr[].y[a]+tr[].y[b])/(tr[].x[a]+tr[].x[b]);
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%lf",&p1[i].x);
for(int i=;i<=n;i++)scanf("%lf",&p1[i].y);
for(int i=;i<=n;i++)scanf("%lf",&p2[i].x);
for(int i=;i<=n;i++)scanf("%lf",&p2[i].y);
for(int f,t,i=;i<n;i++)
{
scanf("%d%d",&f,&t);
ae(f,t),ae(t,f);
}
dfs1(,),dfs2(,);
for(int i=;i<=n;i++)
{
tr[].x[tin[i]]=p1[i].x;
tr[].y[tin[i]]=p1[i].y;
tr[].x[tin[i]]=p2[i].x;
tr[].y[tin[i]]=p2[i].y;
}
tr[].build(,n,);
tr[].build(,n,);
scanf("%d",&m);
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
db las = 2e5 , ans = gt(x,y,las);
while(fabs(ans-las)>1e-)
{
las = ans;
ans = gt(x,y,las);
}
printf("%.4lf\n",ans);
}
return ;
}
bzoj2402 陶陶的难题II的更多相关文章
- [BZOJ2402]陶陶的难题II(树链剖分+线段树维护凸包+分数规划)
陶陶的难题II 时间限制:40s 空间限制:128MB 题目描述 输入格式 第一行包含一个正整数N,表示树中结点的个数. 第二行包含N个正实数,第i个数表示xi (1<=xi<= ...
- bzoj 2402: 陶陶的难题II 二分答案维护凸包
2402: 陶陶的难题II Time Limit: 40 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 68 Solved: 45[Submi ...
- BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)
前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...
- 【BZOJ2401】陶陶的难题I 欧拉函数+线性筛
[BZOJ2401]陶陶的难题I 题意:求,n<=1000000,T<=100000 题解:直接做是n*sqrt(n)的,显然会TLE,不过这题a和b都是循环到n,那么就可以进行如下的神奇 ...
- bzoj 2401: 陶陶的难题I 数论
2401: 陶陶的难题I Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 89 Solved: 24[Submit][Status] Descript ...
- P1676陶陶吃苹果 - vijos
描述 curimit知道陶陶很喜欢吃苹果.于是curimit准备在陶陶生日的时候送给他一棵苹果树. curimit准备了一棵这样的苹果树作为生日礼物:这棵苹果树有n个节点,每个节点上有c[i]个苹果, ...
- 武汉科技大学ACM:1007: 陶陶摘苹果
Problem Description 厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试. 个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹 ...
- 洛谷-陶陶摘苹果(升级版)-BOSS战-入门综合练习1
题目描述 Description 又是一年秋季时,陶陶家的苹果树结了n个果子.陶陶又跑去摘苹果,这次她有一个a公分的椅子.当他手够不着时,他会站到椅子上再试试. 这次与NOIp2005普及组第一题不同 ...
- NOIP2005-普及组复赛-第一题-陶陶摘苹果
题目描述 Description 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳 ...
- noip普及组2005 陶陶摘苹果
陶陶摘苹果 描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试. 现在 ...
随机推荐
- hdoj5805【模拟】
BestCoder Round #86 B NanoApe Loves Sequence 题意: 中文题,题意就算了 思路: 弱的思路- 找一个最大,和第二大,第三大,标记下标(前面那个) ①:如果是 ...
- 密码(Password)
#include<cstdio> #include<cstring> using namespace std; int k, cnt; ][][], ans[]; bool d ...
- Linux下rpm、yum和源码三种安装方式详细介绍
第1章 源码安装 源码包安装会比RPM包安装慢,是因为RPM的软件包是根据特定系统和平台而指定的,经常一种 程序会提供很多RPM包的格式,用户根据系统情况选择适合的RPM包直接安装,而源码包相当于 通 ...
- Jenkins持续集成多任务之MultiJob
项目实践中,我们可能需要在多个任务发布成功后在执行某个任务,这里就需要用到MultiJob这个插件. 案例场景:有3个任务:A.B.C,其中C任务需要等A和B执行成功后才会执行,那么就要先执行A和B, ...
- 洛谷 P3480 [POI2009]KAM-Pebbles
https://www.luogu.org/problemnew/solution/P3480 讲不清楚... 首先对原序列做差分:设原序列为a,差分序列为d 那么,每一次按题意在原序列位置i处取走石 ...
- 今天发现一个汉字转换成拼音的模块,记录一下,直接pip install xpinyin即可
http://blog.csdn.net/qq_33232071/article/details/50915760
- 关于list,字符串的小记录
1.关于操作list的命令: a.append("hi") 这个可以在list的最后一项加上个这个字符串"hi",a是list的名字. del a[3] 删去l ...
- Backbone学习记录(5)
数据与服务器 var User=Backbone.Model.extend({ defaults:{ name:'susan', age:18 }, url:'/user'//数据提交的路径 }); ...
- Linux常用命令awk
awk能够处理类似csv这种按行格式的数据,对每一行record按照-F指定的分隔符切割,然后处理.默认支持空格和\t分隔符 1.统计文件里某一列数据等于某个值的个数 -0_djt10.txt 2.拼 ...
- php的iconv函数中utf8与utf-8的差异
开发中遇到一个奇怪的问题:报错如下: iconv() [<a href='function.iconv'>function.iconv</a>] : Wrong charset ...