BZOJ 2402 陶陶的难题II (01分数规划+树剖+线段树+凸包+二分)
题目大意:略
一定范围内求最大值,考虑二分答案
设现在选择的答案是$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分数规划+树剖+线段树+凸包+二分)的更多相关文章
- bzoj2402 陶陶的难题II 分数规划+树剖+线段树维护凸壳+二分
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2402 题解 看上去很像分数规划的模型.于是就二分吧.令 \[ \begin{align*}\f ...
- bzoj 3597: [Scoi2014]方伯伯运椰子 [01分数规划 消圈定理 spfa负环]
3597: [Scoi2014]方伯伯运椰子 题意: from mhy12345 给你一个满流网络,对于每一条边,压缩容量1 需要费用ai,扩展容量1 需要bi, 当前容量上限ci,每单位通过该边花费 ...
- BZOJ 4819 [Sdoi2017]新生舞会 ——费用流 01分数规划
比值最大 分数规划 二分答案之后用费用流进行验证. 据说标称强行乘以1e7换成了整数的二分. 不过貌似实数二分也可以过. #include <map> #include <cmath ...
- bzoj 4034: [HAOI2015]树上操作 (树剖+线段树 子树操作)
4034: [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 6779 Solved: 2275[Submit][Stat ...
- bzoj 3531 [Sdoi2014]旅行 (树剖+线段树 动态开点)
3531: [Sdoi2014]旅行 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 2984 Solved: 1312[Submit][Status ...
- BZOJ 4817: [Sdoi2017]树点涂色(LCT+树剖+线段树)
题目描述 Bob有一棵 nn 个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. Bob ...
- bzoj 5210: 最大连通子块和【动态dp+树剖+线段树+堆】
参考:https://www.cnblogs.com/CQzhangyu/p/8632904.html 要开longlong的 首先看dp,设f[u]为必选u点的子树内最大联通块,p[u]为不一定选u ...
- BZOJ 1576 [USACO]安全路经Travel (树剖+线段树)
题目大意: 给你一张无向图,求1到其他节点 不经过最短路的最后一条边 的最短路长度,保证每个节点的最短路走法唯一 神题,$USACO$题目的思维是真的好 先$dijkstra$出最短路树 对于每个节点 ...
- BZOJ 2243: [SDOI2011]染色 (树剖+线段树)
树链剖分后两个区间合并的时候就判一下相交颜色是否相同来算颜色段数就行了. CODE #include <vector> #include <queue> #include &l ...
随机推荐
- Gym-101615D Rainbow Roads 树的DFS序 差分数组
题目链接:https://cn.vjudge.net/problem/Gym-101615D 题意 给一棵树,每个边权表示一种颜色. 现定义一条彩虹路是每个颜色不相邻的路. 一个好点是所有从该节点开始 ...
- OOP 面向对象 七大原则 (一)
OOP 面向对象 七大原则 (一) 大家众所周知,面向对象有三大特征继承封装多态的同时,还具有这七大原则,三大特征上一篇已经详细说明,这一篇就为大家详解一下七大原则: 单一职责原则,开闭原则,里氏 ...
- 【Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A】 Doggo Recoloring
[链接] 我是链接,点我呀:) [题意] 你可以把出现次数大于1的颜色换成其他颜色. 问你最后能不能全都变成同一种颜色 [题解] 判断一下有没有出现次数大于1的就好. 有的话.显然可以一直用它变颜色. ...
- vue+Ueditor集成 [前后端分离项目][图片、文件上传][富文本编辑]
后端DEMO:https://github.com/coderliguoqing/UeditorSpringboot 前端DEMO:https://github.com/coderliguoqing/ ...
- Ajax-URL 防止数据缓存,添加时间戳
url:CONTEXTPATH + "/dataService/getSourceStatics?type=0&t="+new Date().getTime(),
- windows系统中软件开发常用的软件
1.windwos快速打开控制面板:热键+r打开运行框,输入control就打开windows的控制面板了 2.windows自带的远程桌面控制系统:mstsc -Microsoft terminal ...
- UI组件之AdapterView及其子类(三)Spinner控件具体解释
Spinner提供了从一个数据集合中高速选择一项值的办法. 默认情况下Spinner显示的是当前选择的值.点击Spinner会弹出一个包括全部可选值的dropdown菜单或者一个dialog对话框,从 ...
- [ACM] POJ 2154 Color (Polya计数优化,欧拉函数)
Color Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7630 Accepted: 2507 Description ...
- STL之效率比較
1.vector 变长一维数组,连续存放的内存块,有保留内存.堆中分配内存: 支持[]操作,高效率的随机訪问: 在最后添加元素时,一般不须要分配内存空间,速度快:在中间或開始操作元素时要进行内存拷贝效 ...
- Android 四大组件学习之ContentProvider三
上节课学习怎样自己创建一个ContentProvider.以及用ContentResolver去操作ContentProvider. 今天我们用系统提供的ContentProvider. 先来个简单的 ...