题目大意:略

一定范围内求最大值,考虑二分答案

设现在选择的答案是$mid$,$max \left \{ \frac{yi+qj}{xi+pj} \right \} \geq mid $

展开可得,$(yi-mid*xi)+(qj-mid*pj)>=0$,只要存在$i,j$使得这个式子成立,说明$mid$能作为答案

题目并没有要求我们不能选择同一个节点,所以$i,j$之间没有任何关联

现在需要求出$max \left \{ yi-mid*xi \right \}$,$q,p$和$x,y$同理

移项,$yi=mid*xi+b$,求$b$的最大值,发现这是一个一次函数的形式

线段树维护树链剖分序,线段树上每个节点都挂一个上凸包,每次用一条斜率为$mid$的直线去切这个凸包即可

总时间$O(nlog^{4}n)$,理论上过不去,但#巨佬说跑不满

 #include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 30010
#define S1 (N1<<1)
#define T1 (N1<<2)
#define ll long long
#define uint unsigned int
#define rint register int
#define dd double
#define il inline
#define inf 233333333
using namespace std; const dd eps=0.000001;
int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
int n,m;
struct Edge{
int to[S1],nxt[S1],head[N1],cte;
void ae(int u,int v)
{cte++,to[cte]=v,nxt[cte]=head[u],head[u]=cte;}
}E;
struct node{int id;dd val;}tmp[N1];
int cmp1(node s1,node s2){return s1.val<s2.val;}
int stk[N1];
struct SEG{
vector<int>cvh[T1];
void build(int l,int r,int rt,int *A,dd *X,dd *Y)
{
int i,j,cnt=,tp=,mid;
for(i=l;i<=r;i++) cnt++,tmp[cnt].id=A[i],tmp[cnt].val=X[A[i]];
sort(tmp+,tmp+cnt+,cmp1);
stk[++tp]=tmp[].id;
for(i=;i<=cnt;i++)
{
j=tmp[i].id;
while(tp>&&(Y[j]-Y[stk[tp-]])*(X[stk[tp]]-X[stk[tp-]])>=(Y[stk[tp]]-Y[stk[tp-]])*(X[j]-X[stk[tp-]])) tp--;
stk[++tp]=j;
}
for(i=;i<=tp;i++) cvh[rt].push_back(stk[i]);
if(l==r) return;
mid=(l+r)>>;
build(l,mid,rt<<,A,X,Y);
build(mid+,r,rt<<|,A,X,Y);
}
dd cvh_query(int rt,dd K,dd *X,dd *Y)
{
if(cvh[rt].size()==) return Y[cvh[rt][]]-X[cvh[rt][]]*K;
int i,l=,r=cvh[rt].size()-,mid,p=,a,b;
a=cvh[rt][],b=cvh[rt][];
if((Y[b]-Y[a])<=K*(X[b]-X[a])) return Y[a]-X[a]*K;
while(l<=r){
mid=(l+r)>>,a=cvh[rt][mid-],b=cvh[rt][mid];
if((Y[b]-Y[a])>=K*(X[b]-X[a])) p=mid,l=mid+;
else r=mid-;
}return Y[cvh[rt][p]]-X[cvh[rt][p]]*K;
}
dd query(int L,int R,int l,int r,int rt,dd K,dd *X,dd *Y)
{
if(L<=l&&r<=R)
return cvh_query(rt,K,X,Y);
int mid=(l+r)>>; dd ans=-inf;
if(L<=mid) ans=max(ans,query(L,R,l,mid,rt<<,K,X,Y));
if(R>mid) ans=max(ans,query(L,R,mid+,r,rt<<|,K,X,Y));
return ans;
}
}xy,pq;
dd X[N1],Y[N1],P[N1],Q[N1];
namespace cut{
int fa[N1],dep[N1],sz[N1],son[N1],tp[N1];
int st[N1],id[N1],tot;
void dfs1(int u,int ff)
{
for(int j=E.head[u];j;j=E.nxt[j])
{
int v=E.to[j];
if(v==ff) continue;
dep[v]=dep[u]+; fa[v]=u; dfs1(v,u);
sz[u]+=sz[v]; son[u]=sz[v]>sz[son[u]]?v:son[u];
}
sz[u]++;
}
void dfs2(int u)
{
st[u]=++tot,id[tot]=u;
if(son[u]) tp[son[u]]=tp[u], dfs2(son[u]);
for(int j=E.head[u];j;j=E.nxt[j])
{
int v=E.to[j];
if(v==fa[u]||v==son[u]) continue;
tp[v]=v; dfs2(v);
}
}
dd query(int x,int y,dd K)
{
dd mxy=-inf,mpq=-inf;
while(tp[x]!=tp[y])
{
if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
mxy=max(mxy,xy.query(st[tp[x]],st[x],,n,,K,X,Y));
mpq=max(mpq,pq.query(st[tp[x]],st[x],,n,,K,P,Q));
x=fa[tp[x]];
}
if(dep[x]>dep[y]) swap(x,y);
mxy=max(mxy,xy.query(st[x],st[y],,n,,K,X,Y));
mpq=max(mpq,pq.query(st[x],st[y],,n,,K,P,Q));
return mxy+mpq;
}
void init()
{
dep[]=,dfs1(,-);
tp[]=,dfs2();
xy.build(,n,,id,X,Y);
pq.build(,n,,id,P,Q);
}
}; int main()
{
scanf("%d",&n);
int i,x,y;
for(i=;i<=n;i++) scanf("%lf",&X[i]);
for(i=;i<=n;i++) scanf("%lf",&Y[i]);
for(i=;i<=n;i++) scanf("%lf",&P[i]);
for(i=;i<=n;i++) scanf("%lf",&Q[i]);
for(i=;i<n;i++) x=gint(),y=gint(),E.ae(x,y),E.ae(y,x);
cut::init();
scanf("%d",&m);
dd L,R,mid,ans=;
while(m--)
{
x=gint(),y=gint();
L=,R=1e5;
while(R-L>=eps)
{
mid=(L+R)/;
if(cut::query(x,y,mid)>=) ans=mid,L=mid+eps;
else R=mid-eps;
}
printf("%.4lf\n",ans);
}
return ;
}

BZOJ 2402 陶陶的难题II (01分数规划+树剖+线段树+凸包+二分)的更多相关文章

  1. bzoj2402 陶陶的难题II 分数规划+树剖+线段树维护凸壳+二分

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2402 题解 看上去很像分数规划的模型.于是就二分吧.令 \[ \begin{align*}\f ...

  2. bzoj 3597: [Scoi2014]方伯伯运椰子 [01分数规划 消圈定理 spfa负环]

    3597: [Scoi2014]方伯伯运椰子 题意: from mhy12345 给你一个满流网络,对于每一条边,压缩容量1 需要费用ai,扩展容量1 需要bi, 当前容量上限ci,每单位通过该边花费 ...

  3. BZOJ 4819 [Sdoi2017]新生舞会 ——费用流 01分数规划

    比值最大 分数规划 二分答案之后用费用流进行验证. 据说标称强行乘以1e7换成了整数的二分. 不过貌似实数二分也可以过. #include <map> #include <cmath ...

  4. bzoj 4034: [HAOI2015]树上操作 (树剖+线段树 子树操作)

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 6779  Solved: 2275[Submit][Stat ...

  5. bzoj 3531 [Sdoi2014]旅行 (树剖+线段树 动态开点)

    3531: [Sdoi2014]旅行 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 2984  Solved: 1312[Submit][Status ...

  6. BZOJ 4817: [Sdoi2017]树点涂色(LCT+树剖+线段树)

    题目描述 Bob有一棵 nn 个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. Bob ...

  7. bzoj 5210: 最大连通子块和【动态dp+树剖+线段树+堆】

    参考:https://www.cnblogs.com/CQzhangyu/p/8632904.html 要开longlong的 首先看dp,设f[u]为必选u点的子树内最大联通块,p[u]为不一定选u ...

  8. BZOJ 1576 [USACO]安全路经Travel (树剖+线段树)

    题目大意: 给你一张无向图,求1到其他节点 不经过最短路的最后一条边 的最短路长度,保证每个节点的最短路走法唯一 神题,$USACO$题目的思维是真的好 先$dijkstra$出最短路树 对于每个节点 ...

  9. BZOJ 2243: [SDOI2011]染色 (树剖+线段树)

    树链剖分后两个区间合并的时候就判一下相交颜色是否相同来算颜色段数就行了. CODE #include <vector> #include <queue> #include &l ...

随机推荐

  1. 小松之LINUX驱动学习笔记之模块间函数调用通讯

    1. 符号导出函数 EXPORT_SYMBOL() EXPORT_SYMBOL标签内定义的函数对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用. EXPORT_SYMBOL_GPL( ...

  2. robot Framework选择单选框

  3. ubuntu--dpkg 被中断

    主要原因应该是/var/lib/dpkg/updates 文件夹里面的资料有错误,使得更新软件的程序出现错误,所以得把它们完全删除,通过sudo apt-get update这个指令会重新建立这些资料 ...

  4. [Beginning SharePoint Designer 2010]列表和库&内部内容类型

    本章概要: 1.SPS如何组织管理数据 2.如何创建列表和文档库 3.如何使用视图来过滤分类,分组列表和库 4.如何创建内容类型来应用一个定义好的结构到数据和文档中

  5. jQuery验证所有输入合法后才干提交

    大学三年里所有在专注后台编码.学会不知多少种,servlet.ssh,springMVC,web.py...... 最后每次碰到前端自己要写点东西就满目愁抑, 干脆自己好好理解一段前端代码, 特地拿出 ...

  6. vehicle time series data analysis

    以HADOOP为代表的云计算提供的仅仅是一个算法执行环境,为大数据的并行计算提供了在现有软硬件水平下最好的(近似)方法.并不能解决大数据应用中的全部问题.从详细应用而言,通过物联网方式接入IT圈的数据 ...

  7. node 上传文件 http client to post file

    node做http client 发送post数据是很容易的事情,但要上传文件就不是太容易了主要是因为上传文件的报文和普通post是不太一样的 要了解http post可以看下这个 https://i ...

  8. Codeforces 558B Amr and The Large Array

    B. Amr and The Large Array time limit per test 1 second memory limit per test 256 megabytes input st ...

  9. linux含有某字符串的文件

    find .|xargs grep -ri "IBM" -l 只列出文件名:grep -rn "Item" * -l pattern files

  10. java多线程 interrupt(), interrupted(), isInterrupted()方法区别

    interrupt()方法: 作用是中断线程. 本线程中断自身是被允许的,且"中断标记"设置为true 其它线程调用本线程的interrupt()方法时,会通过checkAcces ...