「CF516D」 Drazil and Morning Exercise
「CF516D」 Drazil and Morning Exercise
这个 \(f_i\) 显然可以通过树形 \(\texttt{DP}\) 直接求。
然后看到这种差值问题感觉就可以二分转换为判定性问题。
哦不好像本来就是判定性问题
显然我们可以考虑枚举最小值,然后检查其他点的合法情况,然后最后查最小值所在连通块大小即可。
这样做是 \(O(n^2\alpha(n))\) 的。
考虑优化。我们猜想这个 \(f\) 一定有性质。
注意到当最小值单调不降的时候,最大值一定也单调不降,也即是说,我们需要确定一个顺序使得我们可以用一个类似于双指针的过程来寻找答案。
有一个非常显然的结论:\(f\) 值最小的节点一定是直径的中点或中点左右的实际节点。
那么有这个东西之后我们可以推得:若以这个点为根,那么一定有 \(f_u<f_{fa_u}\),证明非常简单。
实际上实现的过程中,我们可以对最大值进行枚举,因为最大值的缺失一定不会影响当前连通块的连通性,相当于是以这个 \(f\) 值最小的点为根的某颗子树的叶节点,直接将子树大小减一即可。
然后这个题就完了。
/*---Author:HenryHuang---*/
/*---Never Settle---*/
/*---Never Enough---*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
typedef long long ll;
struct edge{
int to,nex,w;
}e[maxn<<1];
int head[maxn],cnt;
void add(int a,int b,int c){
e[++cnt]=(edge){b,head[a],c};
head[a]=cnt;
}
ll f[maxn],g1[maxn],g2[maxn],cho[maxn];
int ff[maxn];
void dfs1(int u,int fa){
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v==fa) continue;
dfs1(v,u);
if(e[i].w+g1[v]>g1[u]){
g2[u]=g1[u];
g1[u]=e[i].w+g1[v];
cho[u]=v;
}
else g2[u]=max(g2[u],e[i].w+g1[v]);
}
}
void dfs2(int u,int fa){
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v==fa) continue;
if(cho[u]==v) f[v]=max(f[u],g2[u])+e[i].w;
else f[v]=max(f[u],g1[u])+e[i].w;
dfs2(v,u);
}
}
void dfs3(int u,int fa){
ff[u]=fa;
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v==fa) continue;
dfs3(v,u);
}
}
int fa[maxn],siz[maxn],id[maxn];
int getfa(int t){
if(fa[t]==t) return fa[t];
return fa[t]=getfa(fa[t]);
}
void merge(int x,int y){
x=getfa(x),y=getfa(y);
fa[y]=x,siz[x]+=siz[y];
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int n;cin>>n;
for(int i=1;i<n;++i){
int a,b,c;cin>>a>>b>>c;
add(a,b,c),add(b,a,c);
}
dfs1(1,0);
dfs2(1,0);
for(int i=1;i<=n;++i) f[i]=max(f[i],g1[i]);
int mn=1;
for(int i=1;i<=n;++i)
if(f[i]<f[mn]) mn=i;
for(int i=1;i<=n;++i) id[i]=i;
sort(id+1,id+n+1,[&](int x,int y){return f[x]<f[y];});
dfs3(mn,0);
int q;cin>>q;
while(q--){
ll num;cin>>num;
for(int i=1;i<=n;++i) fa[i]=i,siz[i]=1;
int l=n,ans=0;
for(int r=n;r>=1;--r){
while(f[id[r]]-f[id[l]]<=num&&l>1){
--l;
if(f[id[r]]-f[id[l]]<=num){
for(int i=head[id[l]];i;i=e[i].nex){
int v=e[i].to;
if(v==ff[id[l]]) continue;
merge(id[l],v);
}
ans=max(ans,siz[getfa(id[l])]);
}
else{
++l;
break;
}
}
--siz[getfa(id[r])];
}
cout<<ans<<'\n';
}
return 0;
}
「CF516D」 Drazil and Morning Exercise的更多相关文章
- 【CF516D】Drazil and Morning Exercise
题目 首先我们知道,在树上距离一个点最远的点一定是直径的两个端点之一 首先两遍\(\rm dfs\)把直径求出来,定义\(d(u)\)表示点\(u\)距离其最远点的距离,有了直径我们就能求出\(d\) ...
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 「C++」理解智能指针
维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
- 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management
写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...
- 「2014-3-18」multi-pattern string match using aho-corasick
我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...
- 「2014-3-17」C pointer again …
记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...
随机推荐
- 五:.net core(.NET 6)使用Autofac实现依赖注入
Autofac的简单使用: 由于将来可能引用很多包,为了保持统一队形,我们再新建一个类库项目Wsk.Core.Package,当做包的引用集合: 删掉Class1,把Wsk.Core.Wsk.Core ...
- 处理SpringMVC中遇到的乱码问题
乱码在日常开发写代码中是非常常见的,以前乱码使用的是通过设置一个过滤器解决, 现在可以使用SpringMVC给提供的过滤器,在web.xml设置,这比我们自己写的过滤器强大的的多. 注意:每次修改了x ...
- Proteus中包含的主流单片机列举
经常使用Proteus的朋友面临的一个问题就是,这个设计用Proteus能仿真吗?在初级阶段,我们仅仅会参考Proteus是否有对应的器件以及器件是否有仿真模型来决断这个问题.有就能仿真,没有就不能仿 ...
- JVM--你常见的jvm 异常有哪些? 代码演示:StackOverflowError , utOfMemoryError: Java heap space , OutOfMemoryError: GC overhead limit exceeded, Direct buffer memory, Unable_to_create_new_native_Thread, Metaspace
直接上代码: public class Test001 { public static void main(String[] args) { //java.lang.StackOverflowErro ...
- Java swing JFrame用repaint出现闪烁的问题解决
这几天用swing写登录页面背景动图的时候发现一直会有闪烁(我的类是继承JFrame),就来搜原因后发现好像是因为repaint会调用update()方法中的清屏操作导致闪烁. 我当时看的是这个文章 ...
- 性能分析之CPU分析-从CPU调用高到具体代码行(C/C++)
今天在培训的过程中,也提到了分析要具体到代码的事情,如果思路方向是正确的,对java应用和C/C++应用来说,也是几个命令就可以跳到代码行了.前提是要能看得懂堆栈信息.所以一直以来我在讲课的过程中都有 ...
- 选择合适Redis数据结构,减少80%的内存占用
redis作为目前最流行的nosql缓存数据库,凭借其优异的性能.丰富的数据结构已成为大部分场景下首选的缓存工具. 由于redis是一个纯内存的数据库,在存放大量数据时,内存的占用将会非常可观.那么在 ...
- 如何编写shell脚本
1.首先创建一个目录 vi hello.sh 2.编写shell第一行 #!/bin/bash (为了声明是shell脚本,第一行都要这么写) 3.可以添加注释 #the first p ...
- conn / as sysdba连接不上
问题: SQL> conn / as sysdbaERROR:ORA-09817: Write to audit file failed.Linux-x86_64 Error: 28: No s ...
- DOS命令行(2)——Windows磁盘维护与管理
预备知识 1 -- 磁盘 1.磁盘分区 主磁盘分区.扩展磁盘分区.逻辑分区 主磁盘分区是物理磁盘的一部分,它像物理上独立的磁盘那样工作.对于基本启动记录(MBR)的磁盘,在一个基本磁盘上最多可以创建四 ...