此题niubi!

题目大意:给你一颗n个点的点带权无根树,现在请您进行以下两步操作:

1,选择一个$[0,T]$之间的整数$C$,并令所有的点权$wi$变为$(wi+C)%MOD$

2,选择若干条点不相交的路径;设选择的条数为$k$,覆盖的点的点权和为$S$,则收益为$\frac{S}{k+1}$

请您求出收益最大可能为多少。

数据范围:$T,S≤10^5$,$n≤5000$

我们先不考虑修改点权的过程,只考虑求最大收益应该如何做。

我们显然有一种$O(n^2)$的做法,但是复杂度太高了,加上修改点权的操作就爆炸了,考虑优化。

我们考虑二分这个收益,设当前二分到的收益是$ans$。

假设真实收益大于$ans$,则有:

$\frac{S}{k+1}>ans$

我们进行移项,有:

$S-k\times ans>ans$

这个式子为啥会优秀很多呢?因为$S-k\times ans$可以在$O(n)$的时间内求出了:

我们设$f[u]$表示以$u$为跟的子树内找出了$x$条路径,($x$条路径的和$-x\times ans$)的最大值,且没有路径连出$u$

$g[u]$表示以$u$为跟的子树内找出了$x$条路径,($x$条路径的和$-(x-1)\times ans$)的最大值,有恰好一条路径从$u$连出

我们在以$u$为跟的子树中找出两个儿子$v1$,$v2$,满足$v1$在所有儿子中,$g[v1]-f[v1]$最大,$v2$次大。

设$S=\sum \limits_{v∈son[u]} f[u]$,则有:

$f[u]=max(S,S+(g[v1]-f[v1])+(g[v2]-f[v2]+val[u])-ans)$

$g[u]=max(S,S+(g[v1]-f[v1])+val[u])$

其中$val[u]$表示点$u$的权值。

我们通过二分$ans$,就可以在$O(n\log(-\varepsilon))$确定当前最大的$ans$。

我们考虑点权的修改,一个有效的点权修改方案,需满足至少一个$val[i]$被修改至$MOD-1$,或者增加的值为$T$。

如果每次暴力修改,然后二分查找$ans$,这个复杂度显然是$O(n\log(-\varepsilon))$的,依然会爆炸。

设$Ans[i]$表示当点权被增加了$c[i]$时的$ans$

我们考虑到,一个长度为$n$的随机序列的最长上升子序列期望长度是$O(\log\  n)$的

我们考虑将序列$C$随机打乱

我们先将序列进行修改,然后基于之前求出的$ans$,求一遍答案,判断修改后的序列是否会更加优秀。

如果更加优秀,我们就重新二分出答案。

不难发现,重新二分答案的次数期望是$O(\log\ n)$的。

总的复杂度就是$O(n^2+n\log n\log(-\varepsilon))$的。

完结撒花

 #include<bits/stdc++.h>
#define M 5005
#define eps 1e-6
using namespace std; struct edge{int u,next;}e[M*]={}; int head[M]={},use=;
void add(int x,int y){use++;e[use].u=y;e[use].next=head[x];head[x]=use;} double f[M]={},g[M]={},Ans=;
double get(int x){return g[x]-f[x];} int n,MOD,T,val[M]={},Val[M]={}; void dfs(int x,int fa){
int max1=,max2=;
double sumf=;
for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa){
int v=e[i].u;
dfs(v,x);
if(get(v)>get(max1)) max2=max1,max1=v;
else if(get(v)>get(max2)) max2=v;
sumf+=f[v];
}
f[x]=max(sumf,sumf+get(max1)+get(max2)+val[x]-Ans);
g[x]=max(max(sumf,sumf+val[x]),sumf+get(max1)+val[x]);
} int cnt=,c[M]={}; bool check(double chg){
Ans=chg;
dfs(,);
return f[]>=chg-eps;
} int main(){
scanf("%d%d",&n,&MOD);
for(int i=;i<=n;i++) scanf("%d",Val+i),Val[i]%=MOD;
for(int i=,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
scanf("%d",&T);
c[++cnt]=; c[++cnt]=T;
for(int i=;i<=n;i++){
c[++cnt]=MOD--Val[i];
if(c[cnt]>T){c[cnt--]=; continue;}
}
memcpy(val,Val,sizeof(val)); random_shuffle(c+,c+cnt+);
double ans=;
for(int hh=;hh<=cnt;hh++){
for(int i=;i<=n;i++) val[i]=(Val[i]+c[hh])%MOD;
if(!check(ans)) continue;
double l=,r=n*MOD/;
while(r-l>eps){
double mid=(l+r)/;
if(check(mid)) l=mid;
else r=mid;
}
ans=max(ans,l);
}
printf("%.10lf\n",ans);
}

【2019北京集训六】路径(path) 二分+DP的更多相关文章

  1. 【2019北京集训3】逻辑 树剖+2-sat

    题目大意:有一颗有$m$个叶子节点的二叉树. 对于叶子节点$i$,$x[i]=(a[i]\ xor\ V_{p[i]})or(b[i]\ xor\ V_{q[i]})$ 对于非叶子节点$i$,$x[i ...

  2. 【2019北京集训测试赛(十三)】数据(sj) 冷静分析

    题目大意:给你一个代表区间$[1,n]$的线段树,问你随机访问区间$[1,n]$中的一个子区间,覆盖到的线段树节点个数的期望(需要乘上$\frac{n(n-1)}{2}$后输出). 数据范围:$n≤1 ...

  3. 【2019北京集训测试赛(七)】 操作 分治+FFT+生成函数

    题目大意:你有$n$个操作和一个初始为$0$的变量$x$. 第$i$个操作为:以$P_i$的概率给$x$加上$A_i$,剩下$1-P_i$的概率给$x$乘上$B_i$. 你袭击生成了一个长度为$n$的 ...

  4. 【2019北京集训2】Elephant 平衡树

    题目大意:给你一个长度为$n$的序列$A_i$,有$q$次操作,每次操作为以下三种之一: 询问区间的$F_M(A_i)$的最大公约数. 区间翻转,区间加一个正数. 我们定义$gcd(0,0)=0$,且 ...

  5. 【2019北京集训2】duck 线段树优化建图+tarjan

    题目大意:给你$n$个点,第$i$个点有点权$v_i$.你需要将这$n$个点排成一排,第$i$个点的点权能被累加当且仅当这个点前面存在编号在$[l_i,r_i]$中的点,问你这些点应该如何排列,点权和 ...

  6. (2016北京集训十)【xsy1528】azelso - 概率期望dp

    北京集训的题都是好题啊~~(于是我爆0了) 注意到一个重要的性质就是期望是线性的,也就是说每一段的期望步数可以直接加起来,那么dp求出每一段的期望就行了... 设$f_i$表示从$i$出发不回到$i$ ...

  7. 【北京集训D2T3】tvt

    [北京集训D2T3]tvt \(n,q \le 1e9\) 题目分析: 首先需要对两条路径求交,对给出的四个点的6个lca进行分类讨论.易于发现路径的交就是这六个lca里面最深的两个所形成的链. 然后 ...

  8. SVG 学习<八> SVG的路径——path(2)贝塞尔曲线命令、光滑贝塞尔曲线命令

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  9. SVG 学习<七> SVG的路径——path(1)直线命令、弧线命令

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

随机推荐

  1. sed 笔记

    sed是一个非交互式文本编辑器,他可以对文本文件和标准输入进行编辑,标准输入可以是来自键盘,文件重定向,字符串,变量甚至来自于管道的文本.sed适用于以下三种场合: 编辑相对交互式文本编辑器而言太大的 ...

  2. zabbix-3.4.10系列

    第1节 zabbix体系架构图:

  3. CentOS开机报错:sd 0:0:0:0: [sda] Assuming drive cache: write through

    解决方法: vim /etc/default/grub 文件里去掉 rhgb 参数. [root@lb-nginx- ~/]#vim /etc/default/grub GRUB_TIMEOUT= G ...

  4. FOB cost---从工厂到码头的费用

    1.主要是港杂费:陆运400元起,2个方450元,三个方500元,3个方以上按100元/方算起.

  5. 100-days: thirteen

     Title: “The Godfather turns 50” <教父>50周年 turn 达到某个年龄 Mario Puzo's(马里奥·普佐) "The Godfather ...

  6. Windows Server 2016离线安装.NET Framework 3.5

    windows server 2016默认是不安装.netframework3.5的,可以在添加删除程序中单独添加.但是有时候系统安装文件不在的时候,找不到安装程序就不能安装成功. 这时候单独下载do ...

  7. 365. Water and Jug Problem量杯灌水问题

    [抄题]: 简而言之:只能对 杯子中全部的水/容量-杯子中全部的水进行操作 You are given two jugs with capacities x and y litres. There i ...

  8. canvas(一) 基本线条绘制

    var dom = document.getElementById('canvasItem'), ctx = dom.getContext('2d'); //坐标位置默认基于 浏览器窗口(0,0),此 ...

  9. Android 记录点滴

    1:关于断点 设置断点点三角是进不去的,这个是类似c#的release 正式版, 点第二个红圈内的debug的那个按钮才可以   . 这个按钮可以让程序及时进入当前断点处 2:对于背景颜色 andro ...

  10. 设置angular公共样式表

    一.现象 新创建的项目,是直接显示在src目录下的,假如会用到其它第三方的全局样式时,不能统一放在一个地方统一来管理,就会感觉有点乱. 二.解决 1.移动样式表. 在assets文件夹(该文件夹一般都 ...