思路:

1. 如果根节点是0,那么可以通过一次dfs计算出所有节点的最大值。

2. 如果根节点不是0,那么其余各点的最大值一定是根节点的一个因子。首先计算出根节点的所有因子。在dfs到一个深度为d的节点v时,遍历所有因子:对于因子x,p表示从根节点到达v的路径中能够被x整除的节点个数。如果p >= d - 1,则x就是当前节点的一个候选最大值(d-1是因为可以把路径中其中一个数替换为0)。

于是通过两次dfs即可得出答案。复杂度O(n * sqrt(n))。在dfs的过程中,要注意维护全局变量。dfs到下一个分支时,要把上一个分支对全局变量造成的影响消除。

实现:

 #include <bits/stdc++.h>
using namespace std;
int a[], val[];
vector<int> tree[];
int vis[];
int divisors[]; void dfs(int cur, int div)
{
vis[cur] = ;
for (int i = ; i < tree[cur].size(); i++)
{
int tmp = tree[cur][i];
if (vis[tmp]) continue;
val[tmp] = __gcd(div, a[tmp]);
dfs(tmp, val[tmp]);
}
} void dfs2(int cur, int d, vector<int>& v)
{
vis[cur] = ;
for (int i = ; i < tree[cur].size(); i++)
{
int tmp = tree[cur][i];
if (vis[tmp]) continue;
for (int j = ; j < v.size(); j++)
{
if (a[tmp] % v[j] == ) divisors[j]++;
if (divisors[j] >= d) val[tmp] = max(val[tmp], v[j]);
}
dfs2(tmp, d + , v);
for (int j = ; j < v.size(); j++)
if (a[tmp] % v[j] == ) divisors[j]--;
}
} int main()
{
int n, x, y;
while (cin >> n)
{
for (int i = ; i <= n; i++)
tree[i].clear();
for (int i = ; i <= n; i++)
cin >> a[i];
for (int i = ; i < n - ; i++)
{
cin >> x >> y;
tree[x].push_back(y);
tree[y].push_back(x);
}
int tmp = a[];
a[] = ;
memset(vis, , sizeof vis);
dfs(, );
a[] = val[] = tmp;
vector<int> v;
for (int i = ; i * i <= a[]; i++)
{
if (a[] % i == )
{
v.push_back(i);
if (a[] / i != i) v.push_back(a[] / i);
}
}
sort(v.begin(), v.end());
for (int i = ; i < v.size(); i++) divisors[i] = ;
memset(vis, , sizeof vis);
dfs2(, , v);
for (int i = ; i <= n; i++)
cout << val[i] << " ";
cout << endl;
}
return ;
}

CF842C Ilya And The Tree的更多相关文章

  1. 【cf842C】 Ilya And The Tree(dfs、枚举因子)

    C. Ilya And The Tree 题意 给一棵树求每个点到根的路上允许修改一个为0,gcd的最大值. 题解 g是从根到当前点允许修改的最大gcd,gs为不修改的最大gcd.枚举当前点的因子,更 ...

  2. Codeforces Round #430 (Div. 2) C. Ilya And The Tree

    地址:http://codeforces.com/contest/842/problem/C 题目: C. Ilya And The Tree time limit per test 2 second ...

  3. C. Ilya And The Tree 树形dp 暴力

    C. Ilya And The Tree 写法还是比较容易想到,但是这么暴力的写法不是那么的敢写. 就直接枚举了每一个点上面的点的所有的情况,对于这个点不放进去特判一下,然后排序去重提高效率. 注意d ...

  4. codeforces 842C Ilya And The Tree

    Ilya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very ...

  5. Codeforces Round #430 C. Ilya And The Tree

    Ilya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very ...

  6. C - Ilya And The Tree Codeforces Round #430 (Div. 2)

    http://codeforces.com/contest/842/problem/C 树 dp 一个数的质因数有限,用set存储,去重 #include <cstdio> #includ ...

  7. Codeforces 842C Ilya And The Tree 树上gcd

    题目链接 题意 给定一棵根为\(1\)的树.定义每个点的美丽值为根节点到它的路径上所有点的\(gcd\)值.但是对于每个点,在计算它的美丽值时,可以将这条路径上某个点的值变为\(0\)来最大化它的美丽 ...

  8. Ilya And The Tree CodeForces - 842C

    ((半个)智商题,主要难度在于实现) 题意:有一棵n个结点组成的树,其根是编号为1的结点.对于每一个结点,生成从根结点走到这个结点的路径(包括自身),选择路径上的一个点或者不选择任何点,使得其它点的最 ...

  9. codeforces 842C Ilya And The Tree (01背包+dfs)

    (点击此处查看原题) 题目分析 题意:在一个树中,有n个结点,记为 1~n ,其中根结点编号为1,每个结点都有一个值val[i],问从根结点到各个结点的路径中所有结点的值的gcd(最大公约数)最大是多 ...

随机推荐

  1. systemtap 作用-- SystemTap使用技巧

    http://blog.csdn.net/wangzuxi/article/details/42849053

  2. Qt实现Windows远程控制

    实现方式为server端+client. server端为一个进程.client为图形界面程序. client连接时设置server端的Ip地址,以及须要显示的长度和宽度(不能超过相应server端显 ...

  3. C# .NET 如何批量增加或取消注释

    选中一批文本之后 批量增加注释:Ctrl+K Ctrl+C 批量取消注释:Ctrl+K Ctrl+U  

  4. 算法基础:正整数指定规则排序问题(Golang实现)

    给定字符串内有非常多正整数,要求对这些正整数进行排序.然后返回排序后指定位置的正整数 排序要求:依照每一个正整数的后三位数字组成的整数进行从小到大排序 1)假设不足三位,则依照实际位数组成的整数进行比 ...

  5. HTML5开发移动web应用——SAP UI5篇(6)

    <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255) ...

  6. CentOS 6.4安装Ganglia

    samba 1.这里安装的是3.1.7版本,web前端是最新版本,安装前期环境(yum源用的是本地的) yum -y insatll php php-gd rrdtools apr-devel apr ...

  7. train_action

    # 导入数值计算模块 import numpy as np import tensorflow as tf # 创建计算会话 sess = tf.Session() # 生成数据,创建占位符和变量A ...

  8. C#中,JSON字符串转换成对象。

    在前台提交(post)的数据中.除了强类型的数据外,还有一个额外的json数据提交 在这里我的办法是,在前台把json对象转换成字符串,然后提交. 测试demo 前台: @using(Html.Beg ...

  9. [Pa2013]Iloczyn

    https://www.zybuluo.com/ysner/note/1300802 题面 给定正整数\(n\)和\(k\),问能否将\(n\)分解为\(k\)个不同正整数的乘积. \(n\leq10 ...

  10. FreeMarker:目录

    ylbtech-FreeMarker:目录 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://yl ...