这个是题目描述:

题解:

啊啊啊啊啊……

垃圾分数规划。

垃圾树链剖分。

垃圾斜率优化。

垃圾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的更多相关文章

  1. [BZOJ2402]陶陶的难题II(树链剖分+线段树维护凸包+分数规划)

    陶陶的难题II 时间限制:40s      空间限制:128MB 题目描述 输入格式 第一行包含一个正整数N,表示树中结点的个数. 第二行包含N个正实数,第i个数表示xi (1<=xi<= ...

  2. bzoj 2402: 陶陶的难题II 二分答案维护凸包

    2402: 陶陶的难题II Time Limit: 40 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 68  Solved: 45[Submi ...

  3. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  4. 【BZOJ2401】陶陶的难题I 欧拉函数+线性筛

    [BZOJ2401]陶陶的难题I 题意:求,n<=1000000,T<=100000 题解:直接做是n*sqrt(n)的,显然会TLE,不过这题a和b都是循环到n,那么就可以进行如下的神奇 ...

  5. bzoj 2401: 陶陶的难题I 数论

    2401: 陶陶的难题I Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 89  Solved: 24[Submit][Status] Descript ...

  6. P1676陶陶吃苹果 - vijos

    描述 curimit知道陶陶很喜欢吃苹果.于是curimit准备在陶陶生日的时候送给他一棵苹果树. curimit准备了一棵这样的苹果树作为生日礼物:这棵苹果树有n个节点,每个节点上有c[i]个苹果, ...

  7. 武汉科技大学ACM:1007: 陶陶摘苹果

    Problem Description 厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试. 个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹 ...

  8. 洛谷-陶陶摘苹果(升级版)-BOSS战-入门综合练习1

    题目描述 Description 又是一年秋季时,陶陶家的苹果树结了n个果子.陶陶又跑去摘苹果,这次她有一个a公分的椅子.当他手够不着时,他会站到椅子上再试试. 这次与NOIp2005普及组第一题不同 ...

  9. NOIP2005-普及组复赛-第一题-陶陶摘苹果

    题目描述 Description 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳 ...

  10. noip普及组2005 陶陶摘苹果

    陶陶摘苹果 描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试. 现在 ...

随机推荐

  1. hdoj5805【模拟】

    BestCoder Round #86 B NanoApe Loves Sequence 题意: 中文题,题意就算了 思路: 弱的思路- 找一个最大,和第二大,第三大,标记下标(前面那个) ①:如果是 ...

  2. 密码(Password)

    #include<cstdio> #include<cstring> using namespace std; int k, cnt; ][][], ans[]; bool d ...

  3. Linux下rpm、yum和源码三种安装方式详细介绍

    第1章 源码安装 源码包安装会比RPM包安装慢,是因为RPM的软件包是根据特定系统和平台而指定的,经常一种 程序会提供很多RPM包的格式,用户根据系统情况选择适合的RPM包直接安装,而源码包相当于 通 ...

  4. Jenkins持续集成多任务之MultiJob

    项目实践中,我们可能需要在多个任务发布成功后在执行某个任务,这里就需要用到MultiJob这个插件. 案例场景:有3个任务:A.B.C,其中C任务需要等A和B执行成功后才会执行,那么就要先执行A和B, ...

  5. 洛谷 P3480 [POI2009]KAM-Pebbles

    https://www.luogu.org/problemnew/solution/P3480 讲不清楚... 首先对原序列做差分:设原序列为a,差分序列为d 那么,每一次按题意在原序列位置i处取走石 ...

  6. 今天发现一个汉字转换成拼音的模块,记录一下,直接pip install xpinyin即可

    http://blog.csdn.net/qq_33232071/article/details/50915760

  7. 关于list,字符串的小记录

    1.关于操作list的命令: a.append("hi") 这个可以在list的最后一项加上个这个字符串"hi",a是list的名字. del a[3] 删去l ...

  8. Backbone学习记录(5)

    数据与服务器 var User=Backbone.Model.extend({ defaults:{ name:'susan', age:18 }, url:'/user'//数据提交的路径 }); ...

  9. Linux常用命令awk

    awk能够处理类似csv这种按行格式的数据,对每一行record按照-F指定的分隔符切割,然后处理.默认支持空格和\t分隔符 1.统计文件里某一列数据等于某个值的个数 -0_djt10.txt 2.拼 ...

  10. php的iconv函数中utf8与utf-8的差异

    开发中遇到一个奇怪的问题:报错如下: iconv() [<a href='function.iconv'>function.iconv</a>] : Wrong charset ...