题目描述

  给定一棵$n$个节点的树,每条边的长度为$1$,同时有一个权值$w$。定义一条路径的权值为路径上所有边的权值的最大公约数。现在对于任意$i\in [1,n]$,求树上所有长度为$i$的简单路径中权值最大的是多少。如果不存在长度为$i$的路径,则第$i$行输出$0$。


输入格式

第一行,一个整数$n$,表示树的大小。
接下来$n-1$行,每行三个整数$u,v,w$,表示$u,v$间存在一条权值为$w$的边。


输出格式

对于每种长度,输出一行,表示答案。


样例

样例输入:

3
1 2 3
1 3 9

样例输出:

9
3
0


数据范围与提示

对于$30\%$的数据,$n\leqslant 1,000$。
对于额外$30\%$的数据,$w\leqslant 100$。
对于$100\%$的数据,$n\leqslant 4\times 10^5,1\leqslant u,v\leqslant n,w\leqslant 10^6$。


题解

直接处理很难,考虑如何转化问题。

将问题反过来,也就是转化为对于每一个$gcd$,将其倍数的边建树,建成一棵森林,求树的直径,对于一样的直径,我们只要那棵$gcd$最大的树的$gcd$就好了。

时间复杂度:$\Theta(n\sqrt{w})$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct node{int nxt,to,w;}e[800000];
int head[400001],cnt;
int n;
int mxw;
int ans[400001];
int mx[400001];
bool vis[400001];
int sta[800001];
vector<pair<int,int>>tr[1000001];
void pre_work()
{
for(int i=1;i<=sta[0];i++)
{
head[sta[i]]=0;
vis[sta[i]]=0;
}
cnt=sta[0]=mxw=0;
}
void add(int x,int y)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
head[x]=cnt;
}
void dfs(int x,int fa)
{
mx[x]=0;
vis[x]=1;
int maxn=0;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=fa)dfs(e[i].to,x);
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=fa)
if(mx[x]<=mx[e[i].to])
{
maxn=mx[x];
mx[x]=mx[e[i].to]+1;
}
else if(maxn<=mx[e[i].to])maxn=mx[e[i].to]+1;
mxw=max(mxw,mx[x]+maxn);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
tr[w].push_back(make_pair(u,v));
}
for(int i=1;i<=1000000;i++)
{
pre_work();
for(int j=i;j<=1000000;j+=i)
{
for(int k=0;k<tr[j].size();k++)
{
add(tr[j][k].first,tr[j][k].second);
add(tr[j][k].second,tr[j][k].first);
sta[++sta[0]]=tr[j][k].first;
sta[++sta[0]]=tr[j][k].second;
}
}
for(int j=1;j<=sta[0];j++)
if(!vis[sta[j]])
dfs(sta[j],0);
ans[mxw]=i;
}
for(int i=n;i;i--)ans[i]=max(ans[i],ans[i+1]);
for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
return 0;
}

rp++

[CSP-S模拟测试]:Walk(树的直径+数学)的更多相关文章

  1. [CSP-S模拟测试]:超级树(DP)

    题目传送门(内部题5) 输入格式 一行两个整数$k$.$mod$,意义见上. 输出格式 一行一个整数,代表答案. 样例 样例输入1: 2 100 样例输出1: 样例输入2: 3 1000 样例输出2: ...

  2. [CSP-S模拟测试]:砍树(数学+模拟)

    题目传送门(内部题1) 输入格式 第一行两个整数$n$,$k$,代表树苗的数量和最大看书的总长度.第二行n个整数$a_i$,代表林先森希望每棵树苗的最终高度. 输出格式 一行一个整数,代表最大可能的d ...

  3. [CSP-S模拟测试]:Walk(BFS+建边)

    题目描述 在比特镇一共有$n$个街区,编号依次为$1$到$n$,它们之间通过若干条单向道路连接. 比特镇的交通系统极具特色,除了$m$条单向道路之外,每个街区还有一个编码${val}_i$,不同街区可 ...

  4. [CSP-S模拟测试]:数学课(找规律+数学)

    题目传送门(内部题145) 输入格式 从$math.in$读入数据. 第一行两个数,为$n,q$.接下来$q$行每行一个数$m$,询问大小为$m$的$A$一共有多少个. 输出格式 输出答案到$math ...

  5. [CSP-S模拟测试]:随(快速幂+数学)

    题目描述 给出$n$个正整数$a_1,a_2...a_n$和一个质数mod.一个变量$x$初始为$1$.进行$m$次操作.每次在$n$个数中随机选一个$a_i$,然后$x=x\times a_i$.问 ...

  6. [CSP-S模拟测试]:神炎皇(数学)

    题目描述 神炎皇乌利亚很喜欢数对,他想找到神奇的数对. 对于一个整数对$(a,b)$,若满足$a+b\leqslant n$且$a+b$是$ab$的因子,则称为神奇的数对.请问这样的数对共有多少呢? ...

  7. [CSP-S模拟测试]:Seat(概率DP+数学)

    题目描述 有$n+2$个座位等距地排成一排,从左到右编号为$0$至$n+1$.最开始时$0$号以及$n+1$号座位上已经坐了一个小$G$,接下来会有$n$个小$G$依次找一个空座位坐下.由于小$G$们 ...

  8. [CSP-S模拟测试]:夜鹰与玫瑰(数学)

    题目描述 红晕爬上了白玫瑰的花瓣,花刺还没有到达夜莺的心脏,玫瑰的心依旧苍白如终年不化的积雪.由生命铸就的玫瑰不允许存在一丝一毫的瑕疵,假设玫瑰的一片花瓣可以抽象成一个点,一朵玫瑰我们用一个$N\ti ...

  9. [CSP-S模拟测试]:玄学题/c(数学)

    题目传送门(内部题40) 输入格式 第一行:两个正整数$n$.$m$. 输出格式 第一行:一个整数,代表式子的值. 样例 样例输入1: 4 5 样例输出1: 0样例输入2: 799 8278 样例输出 ...

随机推荐

  1. Parcel在binder通信readStrongBinder和writeStrongBinder

    Binder IPC通信中,Binder是通信的媒介,Parcel是通信的內容.远程调用过程中,其参数都被打包成Parcel的形式来传递. 在IPC通信的Proxy端,我们经常可以看到下面类似的代码, ...

  2. 基于3ds Max的游戏建模方案

    前言 需求 由于本游戏的设计,需求使用到角色以及场景建模.具体模型的搭建与贴图的设计根据原画进行. 工具 一般在游戏研发中,模型的搭建主要使用以下工具和概念来渲染建模. 3ds Max 3ds Max ...

  3. 红黑树的删除操作---以JDK源码为例

    删除操作需要处理的情况: 1.删除的是红色节点,则删除节点并不影响红黑树的树高,无需处理. 2.删除的是黑色节点,则删除后,删除节点所在子树的黑高BH将减少1,需要进行调整. 节点标记: 正在处理的节 ...

  4. 编写 Chrome 扩展——contextMenus 的快捷创建

    1 写在前面 最近使用 typescript 与 angular 编写 chrome 扩展, 对繁复的 contextMenus 创建步骤进行了提炼,并总结一个类 2 重构思路 2.1 一般方法 在编 ...

  5. Java WebService 参考文档

    webservice 基础使用 java 与tomcat使用http://cxshun.iteye.com/blog/1275408 spring mvc中使用https://www.cnblogs. ...

  6. [Git] 007 三棵树以及向本地仓库加入第一个文件

    1. "三棵树" 1.1 前言 理论上要稍稍复杂一点 我在这里说得简化一点 顺道挖个坑 下回具体介绍 坑号编码:Git07-1 1.2 看图 1.3 简介 树左:工作区(平时写代码 ...

  7. Sentinel整合Dubbo限流实战(分布式限流)

    之前我们了解了 Sentinel 集成 SpringBoot实现限流,也探讨了Sentinel的限流基本原理,那么接下去我们来学习一下Sentinel整合Dubbo及 Nacos 实现动态数据源的限流 ...

  8. 大数加减(51nod)

    1005 大数加法 给出2个大整数A,B,计算A+B的结果.     输入 第1行:大数A 第2行:大数B (A,B的长度 <= 10000 需注意:A B有可能为负数) 输出 输出A + B ...

  9. SCUT - 37 - 手速帝CZK - 分块

    https://scut.online/p/37 一开始想到要根号分块预处理,但是不太懂具体怎么写.想不到如此暴力. #include<bits/stdc++.h> using names ...

  10. python 搜索路径顺序查找

    但我们通过 import 或者frome .. import...查找模块的时候,当你导入一个模块,Python 解析器对模块位置的搜索顺序是 1.当前目录 2, 如果不在当前目录,Python 则搜 ...