BZOJ2402: 陶陶的难题II(树链剖分,0/1分数规划,斜率优化Dp)
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
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
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)的更多相关文章
- [BZOJ2402]陶陶的难题II(树链剖分+线段树维护凸包+分数规划)
陶陶的难题II 时间限制:40s 空间限制:128MB 题目描述 输入格式 第一行包含一个正整数N,表示树中结点的个数. 第二行包含N个正实数,第i个数表示xi (1<=xi<= ...
- BZOJ 2402 陶陶的难题II (树链剖分、线段树、凸包、分数规划)
毒瘤,毒瘤,毒瘤-- \(30000\)这个数据范围,看上去就是要搞事的啊... 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2402 ...
- BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)
前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...
- 【模板时间】◆模板·II◆ 树链剖分
[模板·II]树链剖分 学长给我讲树链剖分,然而我并没有听懂,还是自学有用……另外感谢一篇Blog +by 自为风月马前卒+ 一.算法简述 树链剖分可以将一棵普通的多叉树转为线段树计算,不但可以实现对 ...
- BZOJ5210 最大连通子块和 【树链剖分】【堆】【动态DP】
题目分析: 解决了上次提到的<切树游戏>后,这道题就是一道模板题. 注意我们需要用堆维护子重链的最大值.这样不会使得复杂度变坏,因为每个重链我们只考虑一个点. 时间复杂度$O(nlog^2 ...
- 【bzoj2402】陶陶的难题II 分数规划+树链剖分+线段树+STL-vector+凸包+二分
题目描述 输入 第一行包含一个正整数N,表示树中结点的个数.第二行包含N个正实数,第i个数表示xi (1<=xi<=10^5).第三行包含N个正实数,第i个数表示yi (1<=yi& ...
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- 树链剖分+线段树 BZOJ 1036 [ZJOI2008]树的统计Count
题目链接 题意: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节 ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
随机推荐
- CSS 文本字体颜色设置方法(CSS color)
CSS 文本字体颜色设置方法(CSS color) 一.认识CSS 颜色(CSS color) 这里要介绍的是网页设置颜色包含有哪些:网页颜色规定规范. 1.常用颜色地方包含:字体颜色.超链接颜色.网 ...
- 23. Angular 中用 a 标签 href 路由时在浏览器中显示异常 "%2F" 路由失败问题1
这个是angular1.6默认给hash路由上添加了!(感叹号),导致出错,修改方法如下(添加配置,去掉默认前缀感叹号): angular.module('routingDemoApp',['ng ...
- POJ 3184 DP+剪枝
思路: 先找到每i头奶牛能在的位置 (一段区间) 记为L[i]和R[i] f[j]表示在位置j取到的最小值 每回在范围内更新一哈 //By SiriusRen #include <cstdio& ...
- 紫书 习题 10-44 UVa 11246 ( 容斥原理)
把k的倍数的删去(k, 2k, 3k--),但是k^2不应该删去,因为k已经删去,所以不存在某个数乘上k之后为k^2 所以k^2可以留下,然后因为有k^2,所以k^3就是k^2的k倍,所以k^3要删去 ...
- 今日SGU 5.15
最近事情好多,数据库作业,没天要学2个小时java,所以更新的sgu就比较少了 SGU 131 题意:给你两种小块一种,1*1,一种2*2-1*1,问你填满一个m*n的矩形有多少钟方法,n和m小于等于 ...
- Vert.x,一个异步、可伸缩、并发应用框架引发的思考
2012年听说过Vert.x这个框架之后,去年大致了解了下,最近开始进一步熟悉这个框架. Vert.x是一个用于下一代异步.可伸缩.并发应用的框架,旨在为JVM提供一个Node.js的替代方案.开发者 ...
- 03012_预处理对象executeQuery方法(实现数据库的查询)
1.概述 (1)通过预处理对象的executeQuery方法,完成记录的select语句的执行: (2)操作格式统一如下: ①注册驱动: ②获取连接: ③获取预处理对象: ④SQL语句占位符设置实际参 ...
- AES加密解密&&SHA1、SHA加密&&MD5加密
AES加密解密 SHA1.SHA加密 MD5加密 二话不说立即附上代码: package com.luo.util; import java.io.UnsupportedEncodingExcepti ...
- LinkedHashMap<String, Bitmap>(0, 0.75f, true) LinkedHashMap的加载因子和初始容量分配
今天上午在CSDN的论坛里看到有朋友提的问题如下: /** @param maxSize Maximum sum of the sizes of the Bitmaps in this cache * ...
- android 图片特效处理之怀旧效果
图片特效处理系列将介绍图片的像素点的特效处理,这些物资注重的是原理.也就是说只要你知道这些算法不管是C++,VB,C#,Java都可以做出相同的特效.下面将介绍图片怀旧效果的算法.算法如下: 上面公式 ...