P4292-[WC2010]重建计划【长链剖分,线段树,0/1分数规划】
正题
题目链接:https://www.luogu.com.cn/problem/P4292
题目大意
给出\(n\)个点的一棵树,然后求长度在\([L,U]\)之间的一条路径的平均权值最大。
解题思路
先上二分\(0/1\)分数规划,然后变成求最长在\([L,U]\)之间的路径。
很经典的点分治问题,但是用线段树会\(T\),当然可以用单调队列但是我不会。
可以试下上长剖,线段树维护链上每个深度的最大值权值。然后枚举短的那条链的时候在长的那条上面线段树查询就好了。
时间复杂度\(O(n\log^2 n)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
const double inf=1e18,eps=1e-6;
struct node{
int to,next;
double w;
}a[N<<1];
int n,L,U,tot,cnt,ls[N];
int dep[N],len[N],son[N],rt[N];
double f[N],nw[N],ans;
struct SegTree{
double w[N<<5];int ls[N<<5],rs[N<<5];
void Change(int &x,int L,int R,int pos,double val){
if(!x)x=++cnt,ls[x]=rs[x]=0,w[x]=-inf;
if(L==R){w[x]=max(val,w[x]);return;}
int mid=(L+R)>>1;
if(pos<=mid)Change(ls[x],L,mid,pos,val);
else Change(rs[x],mid+1,R,pos,val);
w[x]=max(w[ls[x]],w[rs[x]]);return;
}
double Ask(int x,int L,int R,int l,int r){
if(l<L)l=L;if(r>R)r=R;
if(!x||l>r)return -inf;
if(L==l&&R==r)return w[x];
int mid=(L+R)>>1;
if(r<=mid)return Ask(ls[x],L,mid,l,r);
if(l>mid)return Ask(rs[x],mid+1,R,l,r);
return max(Ask(ls[x],L,mid,l,mid),Ask(rs[x],mid+1,R,mid+1,r));
}
}T;
void addl(int x,int y,double w){
a[++tot].to=y;
a[tot].next=ls[x];
ls[x]=tot;a[tot].w=w;
return;
}
void dfs(int x,int fa){
dep[x]=dep[fa]+1;
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(y==fa)continue;
dfs(y,x);
if(len[y]>len[son[x]])
son[x]=y,nw[x]=a[i].w;
}
len[x]=len[son[x]]+1;
return;
}
void solve(int x,int fa,int t,double k,double dis){
rt[x]=0;
if(son[x])solve(son[x],x,t,k,dis+nw[x]-k);
T.Change(rt[t],dep[t],dep[t]+len[t],dep[x],dis);
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(y==son[x]||y==fa)continue;
solve(y,x,y,k,dis+a[i].w-k);
for(int j=dep[y];j<=dep[y]+len[y];j++){
f[j]=T.Ask(rt[y],dep[y],dep[y]+len[y],j,j);
ans=max(ans,f[j]+T.Ask(rt[t],dep[t],dep[t]+len[t],2*dep[x]+L-j,2*dep[x]+U-j)-2*dis);
}
for(int j=dep[y];j<=dep[y]+len[y];j++)
T.Change(rt[t],dep[t],dep[t]+len[t],j,f[j]);
}
ans=max(ans,T.Ask(rt[t],dep[t],dep[t]+len[t],dep[x]+L,dep[x]+U)-dis);
return;
}
bool check(double k){
ans=T.w[0]=-inf;cnt=0;
solve(1,1,1,k,0);
return ans>-eps;
}
int main()
{
scanf("%d%d%d",&n,&L,&U);
for(int i=1;i<n;i++){
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
addl(x,y,w);addl(y,x,w);
}
len[0]=-1;dfs(1,1);
double l=0,r=1e6;
while(r-l>eps){
double mid=(l+r)/2.0;
if(check(mid))l=mid;
else r=mid;
}
check(1e6);
printf("%.3lf",(l+r)/2.0);
return 0;
}
P4292-[WC2010]重建计划【长链剖分,线段树,0/1分数规划】的更多相关文章
- BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)
前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...
- [WC2010]重建计划 长链剖分
[WC2010]重建计划 LG传送门 又一道长链剖分好题. 这题写点分治的人应该比较多吧,但是我太菜了,只会长链剖分. 如果你还不会长链剖分的基本操作,可以看看我的长链剖分总结. 首先一看求平均值最大 ...
- [BZOJ2402]陶陶的难题II(树链剖分+线段树维护凸包+分数规划)
陶陶的难题II 时间限制:40s 空间限制:128MB 题目描述 输入格式 第一行包含一个正整数N,表示树中结点的个数. 第二行包含N个正实数,第i个数表示xi (1<=xi<= ...
- BZOJ.1758.[WC2010]重建计划(分数规划 点分治 单调队列/长链剖分 线段树)
题目链接 BZOJ 洛谷 点分治 单调队列: 二分答案,然后判断是否存在一条长度在\([L,R]\)的路径满足权值和非负.可以点分治. 对于(距当前根节点)深度为\(d\)的一条路径,可以用其它子树深 ...
- 「WC2010」重建计划(长链剖分/点分治)
「WC2010」重建计划(长链剖分/点分治) 题目描述 有一棵大小为 \(n\) 的树,给定 \(L, R\) ,要求找到一条长度在 \([L, R]\) 的路径,并且路径上边权的平均值最大 \(1 ...
- 洛谷 P4292 - [WC2010]重建计划(长链剖分+线段树)
题面传送门 我!竟!然!独!立!A!C!了!这!道!题!incredible! 首先看到这类最大化某个分式的题目,可以套路地想到分数规划,考虑二分答案 \(mid\) 并检验是否存在合法的 \(S\) ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
- 2019.01.21 bzoj1758: [Wc2010]重建计划(01分数规划+长链剖分+线段树)
传送门 长链剖分好题. 题意简述:给一棵树,问边数在[L,R][L,R][L,R]之间的路径权值和与边数之比的最大值. 思路: 用脚指头想都知道要01分数规划. 考虑怎么checkcheckcheck ...
- [WC2010]重建计划(长链剖分+线段树+分数规划)
看到平均值一眼分数规划,二分答案mid,边权变为w[i]-mid,看是否有长度在[L,R]的正权路径.设f[i][j]表示以i为根向下j步最长路径,用长链剖分可以优化到O(1),查询答案线段树即可,复 ...
随机推荐
- 利用maven构建一个spring mvc的helloworld实例
刚开始学习maven和spring mvc,学的云里雾里的 这里提供一个hello world实例,记录自己的学习之路 首先看maven官网的介绍 Apache Maven is a software ...
- Spring整合Quartz轻松完成定时任务
一.背景 上次我们介绍了如何使用Spring Task进行完成定时任务的编写,这次我们使用Spring整合Quartz的方式来再一次实现定时任务的开发,以下奉上开发步骤及注意事项等. 二.开发环境及必 ...
- 深入浅出Mybatis系列(二)---Mybatis入门
一.Mybatis环境搭建及简单实例 1. 新建web项目, 添加依赖包:mybatis包.数据库驱动包(我使用的是mysql).日志包(我使用的是log4j), 由于我的是maven项目, 那么添加 ...
- 使用dom4j工具:读取xml标签(二)
package dom4j_read; import java.io.File; import java.util.List; import org.dom4j.Document; import or ...
- T-SQL——关于跨库连接查询
目录 0. 同一台服务器不同数据库 1. 使用跨库查询函数--OpenDataSource() 2. 使用链接服务器(Linking Server) 3. 使用OpenDataSource()函数和链 ...
- T-SQL - 习题01_查询每门课都大于80分的学生姓名
时间:2017-09-11 整理:byzqy 题目:用一条SQL语句查询出每门课都大于80分的学生姓名. 最近面试C#开发工程师,碰到上面这个考数据库的题目,自己感觉有点难度,没有思路,现将找到的解决 ...
- 学习小计: Kaggle Learn Embeddings
Embedding表示map f: X(高维) -> Y(低维),减小数据维度,方便计算+提高准确率. 参看Kaggle Learn:https://www.kaggle.com/learn/e ...
- centos7 wget安装Tomcat7
2021-07-15 1.环境介绍 操作系统:centos7 jdk版本:jdk1.8.0.211 tomcat版本:tomcat7.0.109 2. 检查系统中是否已经安装 jdk ,如未安装, 请 ...
- SpringBoot 如何生成接口文档,老鸟们都这么玩的!
大家好,我是飘渺. SpringBoot老鸟系列的文章已经写了两篇,每篇的阅读反响都还不错,果然大家还是对SpringBoot比较感兴趣.那今天我们就带来老鸟系列的第三篇:集成Swagger接口文档以 ...
- 深入xLua实现原理之Lua如何调用C#
xLua是腾讯的一个开源项目,为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力.本文主要是探讨xLua下Lua调用C#的实现原理. Lua与C#数据通信机制 无论是Lua调用C# ...