description

题面

给个树,第\(i\)个点有两个权值\(a_i\)和\(b_i\),现在求一条长度为\(m\)的路径,使得\(\frac{\sum a_i}{\sum b_i}\)最小

data range

\[m\le n\le 2\times 10^5
\]

solution

0/1分数规划?二分吧。

二分一个值\(S\),要使得\(\frac{\sum a_i}{\sum b_i}\le S\)

那么$$\sum(a_i-Sb_i)\le0$$

把每个点的点权做成这个,然后\(DP\ check\)最优答案是否\(\le 0\)就行

如何\(DP\)?

暴力的,\(f_{i,j}\)表示\(i\)子数内长度为\(j\)的链的最优解,转移是\(O(n^2)\)的

按照深度的树上\(DP\)可以使用长链剖分优化到\(O(n)\)

总复杂度就是\(O(nlog\sum w)\)

code

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FILE "cdcq_b"
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-4;
const int mod=998244353;
const int N=200010;
const dd pi=acos(-1);
const int inf=2147483647;
const ll INF=1e18+1;
const ll P=100000;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
} il void file(){
srand(time(NULL)+rand());
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
} int n,m;dd x[N],y[N];
int head[N],nxt[N<<1],to[N<<1],cnt;
int len[N],son[N];
void dfs1(int u,int fa){
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(v==fa)continue;
dfs1(v,u);if(len[son[u]]<len[v])son[u]=v;
}
len[u]=len[son[u]]+1;
} dd *pos,f[N],*A[N],tag[N],ans,K;
void dfs2(int u,int fa){
pos++;A[u]=pos;dd *a=A[u];
if(!son[u]){
a[0]=x[u]*1.0-K*y[u];
if(m==1)ans=min(ans,a[0]);
return;
}
dfs2(son[u],u); tag[u]=tag[son[u]]+x[u]*1.0-K*y[u];
a[0]=x[u]*1.0-K*y[u]-tag[u];
dd *b;
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(v==fa||v==son[u])continue;
dfs2(v,u);b=A[v];
if(m==1)ans=min(ans,b[0]+tag[v]);
else
for(RG int j=0;j<m-1&&j<len[v];j++)
if(m-j-2<len[u])ans=min(ans,b[j]+tag[v]+a[m-j-2]+tag[u]);
for(RG int j=0;j<len[v];j++)
a[j+1]=min(a[j+1],b[j]+tag[v]+x[u]*1.0-K*y[u]-tag[u]);
}
if(len[u]>=m)ans=min(ans,a[m-1]+tag[u]);
} dd g[N];
void dfs3(int u,int fa){
if(!son[u]){g[u]=x[u]*1.0-K*y[u];ans=min(ans,g[u]);return;}
dfs3(son[u],u);if(g[son[u]]<0)g[u]+=g[son[u]];else g[u]=0;
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(v==fa||v==son[u])continue;
dfs3(v,u);ans=min(ans,g[u]+x[u]*1.0-K*y[u]+g[v]);
g[u]=min(g[u],g[v]);
}
g[u]+=x[u]*1.0-K*y[u];ans=min(ans,g[u]);
} il bool check(){
ans=INF;
if(m!=-1){pos=f;memset(f,0,sizeof(f));dfs2(1,0);}
else dfs3(1,0);
return ans<eps;
} int main()
{
file();
RG dd l=0,r=0,mid,as=-INF;
scanf("%d%d",&n,&m);
if(n==1||(m!=-1&&m>=n)){puts("-1");return 0;}
for(RG int i=1;i<=n;i++){scanf("%lf",&x[i]);r+=x[i];}
for(RG int i=1;i<=n;i++){
scanf("%lf",&y[i]);
}
for(RG int i=1,u,v;i<n;i++){
u=read();v=read();
to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;
}
dfs1(1,0); while(r-l>=eps){
K=mid=(l+r)/2;
if(!check())l=mid;
else as=mid,r=mid;
} if(as==-INF)puts("-1");
else printf("%.2lf\n",as);
return 0;
}

[COGS2652]秘术「天文密葬法」的更多相关文章

  1. 【COGS2652】秘术「天文密葬法」(长链剖分,分数规划)

    [COGS2652]秘术「天文密葬法」(长链剖分,分数规划) 题面 Cogs 上面废话真多,建议直接拉到最下面看一句话题意吧: 给个树,第i个点有两个权值ai和bi,现在求一条长度为m的路径,使得Σa ...

  2. cogs 2652. 秘术「天文密葬法」(0/1分数规划 长链剖分 二分答案 dp

    http://cogs.pro:8080/cogs/problem/problem.php?pid=vSXNiVegV 题意:给个树,第i个点有两个权值ai和bi,现在求一条长度为m的路径,使得Σai ...

  3. 2019.03.11 COGS2652 秘术(天文密葬法)(分数规划+长链剖分)

    传送门 题意:nnn个点的树,每个点两个值a,ba,ba,b,问长度为mmm的路径∑ai∑bi\frac{\sum a_i}{\sum b_i}∑bi​∑ai​​的最大值. 思路:一眼要01分数规划, ...

  4. 对于前端,「微信小程序」其实不美好

    微信小程序开放公测了,9月底我曾经写过一篇 「微信小程序」来了,其中最后一句:"谢天谢地,我居然还是个前端". 这种火爆的新事物总是令人激动,感谢这个时代. 但是,当我真作为开发者 ...

  5. macOS安装「oh my zsh」

    目前常用的 Linux 系统和 OS X 系统的默认 Shell 都是 bash,但是真正强大的 Shell 是深藏不露的 zsh, 这货绝对是马车中的跑车,跑车中的飞行车,史称『终极 Shell』, ...

  6. 报名|「OneAPM x DaoCloud」技术公开课:Docker性能监控!

    如今,越来越多的公司开始 Docker 了,「三分之二的公司在尝试了 Docker 后最终使用了它」,也就是说 Docker 的转化率达到了 67%,同时转化时长也控制在 60 天内. 既然 Dock ...

  7. 企业运营对 DevOps 的「傲慢与偏见」

    摘要:出于各种原因,并非所有人都信任 DevOps .有些人觉得 DevOps 只不过给开发者改善产品提供了一个途径而已,还有的人觉得 DevOps 是一堆悦耳的空头支票,甚至有人认为 DevOps ...

  8. 「前端开发者」如何把握住「微信小程序」这波红利?

    由于前两周一直在老家处理重要事情,虽然朋友圈被「微信小程序」刷爆了,但并没有时间深入了解. 昨天回广州之后,第一件事情就是把「微信小程序」相关的文章.开发文档.设计规范全部看了一遍,基本上明白了「微信 ...

  9. 「花田对」CSDN程序员专场——谁来拯救技术宅!_豆瓣

    「花田对」CSDN程序员专场--谁来拯救技术宅!_豆瓣 「花田对」CSDN程序员专场--谁来拯救技术宅!

随机推荐

  1. 【JUC源码解析】AQS

    简介 AQS,也即AbstractQueuedSynchronizer,抽象队列同步器,提供了一个框架,可以依赖它实现阻塞锁和相关同步器.有两种类型,独占式(Exclusive)和共享式(Share) ...

  2. 了解和分析iOS Crash

    WeTest 导读 北京时间凌晨一点,苹果一年一度的发布会如期而至.新机型的发布又会让适配相关的同学忙上一阵子啦,并且iOS Crash的问题始终伴随着移动开发者.本文将从三个阶段,由浅入深的介绍如何 ...

  3. 「日常训练」Skills(Codeforce Round #339 Div.2 D)

    题意(CodeForces 614D) 每个人有\(n(n\le 10^5)\)个技能,技能等级都在\([0,10^9]\)的范围,每个技能有一个当前等级,所有技能的最高等级都为A.一个人的力量被记做 ...

  4. Appium(Python)驱动手机Chrome浏览器

    手机Chrome浏览器访问淘宝H5与在电脑上访问淘宝H5是一摸一样的: 第一种方法: 直接在电脑Chrome浏览器上打开F12: 第二种方法: 手机连接电脑后, 在手机Chrome浏览器上打开淘宝H5 ...

  5. 第五模块·WEB开发基础-第2章JavaScript基础

    第1章 JavaScript基础 01-JavaScript历史介绍 02-JavaScript的组成 03-JavaScript的引入方式 04-变量的使用 05-基本数据类型(一) 06-基本数据 ...

  6. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第6章.蜂巢

    第6章--蜂巢 蜂巢简介 网站开发完,就需要测试.部署.在服务器上运行. 网易蜂巢: 采用Docker容器化技术的云计算平台 https://c.163.com 容器管理:容器可被视作为云主机的服务器 ...

  7. mysql bin log配置及查看

    mysql执行sql可以通过设置mysql bin 日志进行记录查看   mysql bin日志配置如下:   log_bin:on log_bin_basename:bin文件路径及名前缀(/var ...

  8. 【WXS】变量定义保留标识符

    以下字符不能作为变量名称定义: delete void typeof null undefined NaN Infinity var if else true false require this f ...

  9. 【Linux 运维】linux系统关机、重启、注销命令

    linux 关机.重启.注销命令: 关机命令: shutdown -h now 立刻关机(生产常用) shutdown -h  +1  一分钟后关机      (    shutdown -c 可以将 ...

  10. 动画效果 ObjectAnimator

    学习了一下动画效果的使用,做一下笔记 ImageView imageView = findViewById(R.id.imageView); ObjectAnimator.ofFloat(imageV ...