Description

Input

第一行包含一个正整数N,表示树中结点的个数。
第二行包含N个正实数,第i个数表示xi (1<=xi<=10^5)。
第三行包含N个正实数,第i个数表示yi (1<=yi<=10^5)。
第四行包含N个正实数,第i个数表示pi (1<=pi<=10^5)。
第五行包含N个正实数,第i个数表示qi (1<=qi<=10^5)。
下面有N-1行,每行包含两个正整数a,b(1<=a,b<=N),表示树中的边。
第N+5行包含一个正整数M,表示询问的个数。
最后M行,每行包含正整数a,b(1<=a,b<=N),表示一次询问。

Output

共M行,每行一个实数,第i行的数表示第i次询问的答案。
只要你的输出和我们的输出相差不超过0.001即为正确。

Sample Input

5
3.0 1.0 2.0 5.0 4.0
5.0 2.0 4.0 3.0 1.0
1.0 3.0 2.0 4.0 5.0
3.0 4.0 2.0 1.0 4.0
1 2
1 3
2 4
2 5
4
2 3
4 5
2 4
3 5

Sample Output

2.5000
1.5000
1.5000
2.5000

解题思路:

那个式子非常像0/1分数规划。

发现pq式子和xy的式子结构相同,所以用同一种方法维护。

二分答案,看表达式的值。

为了寻找最大值可以将x与y移至方程两侧,发现就是一个直线方程寻找最大截距。

凸包没跑了。

将树链上的点维护成凸包二分答案取值。

开两颗线段树存。

代码:

 #include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lll spc<<1
#define rrr spc<<1|1
typedef long long lnt;
const double eps=1e-;
const int N=;
struct trnt{
int l,r;
};
struct data{
double x,y;
bool friend operator < (data a,data b)
{
return a.x<b.x;
}
}tmp[N];
struct pnt{
int hd;
int fa;
int dp;
int tp;
int wgt;
int ind;
int mxs;
double x,y,p,q;
}p[N];
struct ent{
int twd;
int lst;
}e[N<<];
class segment_tree{
public:
void Build(int l,int r,int spc)
{
int bot=tr[spc].l=top+;
for(int i=l;i<=r;i++)
val[++top]=ln[i];
std::sort(val+tr[spc].l,val+top+);
int cel=top;
top=bot;
for(int i=bot+;i<=cel;i++)
{
while(top>bot&&(val[top].y-val[top-].y)*(val[i].x-val[top].x)<(val[i].y-val[top].y)*(val[top].x-val[top-].x)-eps)
top--;
val[++top]=val[i];
}
tr[spc].r=top;
if(l==r)
return ;
int mid=(l+r)>>;
Build(l,mid,lll);
Build(mid+,r,rrr);
return ;
}
double query(int l,int r,int ll,int rr,int spc,double k)
{
if(l>rr||ll>r)
return -1e9;
if(ll<=l&&r<=rr)
{
double ans;
int L=tr[spc].l;
int R=tr[spc].r;
while(L<R)
{
int mid=(L+R)>>;
if(val[mid+].y-val[mid].y<(val[mid+].x-val[mid].x)*k+eps)
{
R=mid;
}else
L=mid+;
}
ans=val[R].y-val[R].x*k;
return ans;
}
int mid=(l+r)>>;
return std::max(query(l,mid,ll,rr,lll,k),query(mid+,r,ll,rr,rrr,k));
}
void Insert(int l,int r,data *a)
{
for(int i=l;i<=r;i++)
ln[i]=a[i];
return ;
}
private:
trnt tr[N];
data ln[N];
data val[N];
int top;
}S[];
int n,m;
int cnt;
int dfn;
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
void Basic_dfs(int x,int f)
{
p[x].fa=f;
p[x].dp=p[f].dp+;
p[x].wgt=;
int maxs=-;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f)
continue;
Basic_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(maxs<p[to].wgt)
{
maxs=p[to].wgt;
p[x].mxs=to;
}
}
return ;
}
void Build_dfs(int x,int top)
{
if(!x)
return ;
p[x].ind=++dfn;
p[x].tp=top;
Build_dfs(p[x].mxs,top);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].ind)
continue;
Build_dfs(to,to);
}
return ;
}
int Lca(int x,int y)
{
while(p[x].tp!=p[y].tp)
{
if(p[p[x].tp].dp<p[p[y].tp].dp)
std::swap(x,y);
x=p[p[x].tp].fa;
}
if(p[x].dp>p[y].dp)
std::swap(x,y);
return x;
}
bool check(int x,int y,double lambda)
{
double a=-1e9,b=-1e9;
int z=Lca(x,y);
while(p[x].tp!=p[z].tp)
{
a=std::max(S[].query(,n,p[p[x].tp].ind,p[x].ind,,lambda),a);
b=std::max(S[].query(,n,p[p[x].tp].ind,p[x].ind,,lambda),b);
x=p[p[x].tp].fa;
}
a=std::max(S[].query(,n,p[z].ind,p[x].ind,,lambda),a);
b=std::max(S[].query(,n,p[z].ind,p[x].ind,,lambda),b);
while(p[y].tp!=p[z].tp)
{
a=std::max(S[].query(,n,p[p[y].tp].ind,p[y].ind,,lambda),a);
b=std::max(S[].query(,n,p[p[y].tp].ind,p[y].ind,,lambda),b);
y=p[p[y].tp].fa;
}
a=std::max(S[].query(,n,p[z].ind,p[y].ind,,lambda),a);
b=std::max(S[].query(,n,p[z].ind,p[y].ind,,lambda),b);
return a+b>eps;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%lf",&p[i].x);
for(int i=;i<=n;i++)
scanf("%lf",&p[i].y);
for(int i=;i<=n;i++)
scanf("%lf",&p[i].p);
for(int i=;i<=n;i++)
scanf("%lf",&p[i].q);
for(int i=;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
ade(a,b);
ade(b,a);
}
Basic_dfs(,);
Build_dfs(,);
for(int i=;i<=n;i++)
tmp[p[i].ind]=(data){p[i].x,p[i].y};
S[].Insert(,n,tmp);
for(int i=;i<=n;i++)
tmp[p[i].ind]=(data){p[i].p,p[i].q};
S[].Insert(,n,tmp);
S[].Build(,n,);
S[].Build(,n,);
scanf("%d",&m);
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
double l=,r=1e8;
while(fabs(l-r)>=1e-)
{
double mid=(l+r)/2.00;
if(check(a,b,mid))
l=mid;
else
r=mid;
}
printf("%.4lf\n",l);
}
return ;
}
 

BZOJ2402: 陶陶的难题II(树链剖分,0/1分数规划,斜率优化Dp)的更多相关文章

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

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

  2. BZOJ 2402 陶陶的难题II (树链剖分、线段树、凸包、分数规划)

    毒瘤,毒瘤,毒瘤-- \(30000\)这个数据范围,看上去就是要搞事的啊... 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2402 ...

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

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

  4. 【模板时间】◆模板·II◆ 树链剖分

    [模板·II]树链剖分 学长给我讲树链剖分,然而我并没有听懂,还是自学有用……另外感谢一篇Blog +by 自为风月马前卒+ 一.算法简述 树链剖分可以将一棵普通的多叉树转为线段树计算,不但可以实现对 ...

  5. BZOJ5210 最大连通子块和 【树链剖分】【堆】【动态DP】

    题目分析: 解决了上次提到的<切树游戏>后,这道题就是一道模板题. 注意我们需要用堆维护子重链的最大值.这样不会使得复杂度变坏,因为每个重链我们只考虑一个点. 时间复杂度$O(nlog^2 ...

  6. 【bzoj2402】陶陶的难题II 分数规划+树链剖分+线段树+STL-vector+凸包+二分

    题目描述 输入 第一行包含一个正整数N,表示树中结点的个数.第二行包含N个正实数,第i个数表示xi (1<=xi<=10^5).第三行包含N个正实数,第i个数表示yi (1<=yi& ...

  7. BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit ...

  8. 树链剖分+线段树 BZOJ 1036 [ZJOI2008]树的统计Count

    题目链接 题意: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节 ...

  9. 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

    [BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...

随机推荐

  1. hdu2795Billboard(线段树,找第一个大于w的点)

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  2. IDEA中如何设置自动导包

    IDEA跟eclipse还是有一些差别,一些东西要自己去设置,但同时也还是有快捷键的方式来帮助我们 1.如何设置自动导包:如下图所示 点击FIle--->settings 其次还可以通过按快捷键 ...

  3. 大型网站架构之JAVA中间件

    中间件就是在大型网站中,帮助各子模块间实现互相访问,消息共享或统一访问等功能的软件产品.常见的有: 远程服务框架中间件:主要解决各子模块之间互相访问的问题. 消息队列中间件:主要解决各子模之间消息共享 ...

  4. nyoj--38--布线问题(克鲁斯卡尔)

    布线问题 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件: 1.把所有的 ...

  5. linux 不常用命令及命令组合

    lsof:list open files, sudo lsof | grep deleted:则列出虽然被删除,但还处于打开状态的文件.注意,这些文件占用的空间,只有在这些文件关闭时,才会被释放. m ...

  6. NET Remoting原理及应用

    .NET Remoting原理及应用实例: Remoting:(本文摘自百度百科) 简介:        什么是Remoting,简而言之,我们可以将其看作是一种分布式处理方 式.从微软的产品角度来看 ...

  7. 在spring-mybatis.xml 中配置pagehelper

    maven导包:<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</ ...

  8. 15.C语言多线程实现变色龙以及cmd窗口标题变化

    #define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <stdio.h> #include <Wind ...

  9. azkaban(安装配置加实战)

    为什么需要工作流调度系统 一个完整的数据分析系统通常都是由大量任务单元组成:shell 脚本程序,java 程序,mapreduce 程序.hive 脚本等 各任务单元之间存在时间先后及前后依赖关 ...

  10. Java 开发 2.0: 现实世界中的 Redis

    原文地址:http://www.ibm.com/developerworks/cn/java/j-javadev2-22/ 之前,我已在本系列中讨论过 NoSQL 的概念,也介绍了一些与 Java 平 ...