这个是题目描述:

题解:

啊啊啊啊啊……

垃圾分数规划。

垃圾树链剖分。

垃圾斜率优化。

垃圾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. IEnumerable<T> 的时候一个主意事项p

    IEnumerator IEnumerable.GetEnumerator() { return _vtDataView.GetEnumerator(); } public IEnumerator&l ...

  2. AT2534 港湾設備 (Port Facility)

    洛谷 先膜一下Iscream巨巨 首先我们可以把题目转化为线段覆盖,如果两条线段相交(不算某一条完全在另一条里面的情况),那么这两条线段代表的集装箱就不能放到同一个栈里,我们在它们之间连一条边.如果图 ...

  3. 弹射起步~django

    sudo apt-get installl tree 开始创建工作目录 django-admin.py startproject mysite 创建一个名为 mysite的子目录,然后我们通过tree ...

  4. C++ typedef typename 作用

    C++ typedef typename 作用 C++的一些语法让人看着费解,其中就有: typedef typename std::vector<T>::size_type size_t ...

  5. threading多线程模块

    1 基本实现 Thread(target=函数名,args=(以元组形式传递的实参,要加",")) th = threading.Thread(target=run,args=(i ...

  6. HDU - 6063 RXD and math

    Bryce1010模板 http://acm.hdu.edu.cn/showproblem.php?pid=6063 打表发现规律是n^k #include <iostream> #inc ...

  7. loj125 除数函数求和 2

    https://loj.ac/problem/125 $原式=2\sum_{i=1}^n(i^2*{\lfloor}{\frac{n}{i}}{\rfloor})+3\sum_{i=1}^n(i*{\ ...

  8. Two Flowers CodeChef - TWOFL

    https://vjudge.net/problem/CodeChef-TWOFL 先把颜色相同的合并成一个点,建好图,枚举要取的两种颜色(根据图中所有边决定哪些组合要枚举)即可 错误记录: 1.写了 ...

  9. XHTML 1.0 的三种 XML 文档类型 DOCTYPE

    XHTML 1.0 的三种 XML 文档类型 XHTML 1.0 规定了三种 XML 文档类型 XHTML 1.0 Strict <!DOCTYPE html PUBLIC "-//W ...

  10. Spring------自动化装配Bean(一)

    一.创建 CompactDisc接口和SgetPeppers实现类 CompactDisc接口方法为播放.SgtPeppers实现CompactDisc接口. package soundsystem; ...