您的位置:首页 > 其它

Codeforces Round #430 (Div. 2) C. Ilya And The Tree(dfs+最大公约数+因子+树)

2017-08-30 12:27 567 查看
C. Ilya And The Treetime limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputIlya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very interesting tree rooted at vertex 1. Thereis an integer number written on each vertex of the tree; the number written on vertex i is equal to ai.Ilya believes that the beauty of the vertex x is the greatest common divisor of all numbers written on the vertices on the path fromthe root to x, including this vertex itself. In addition, Ilya can change the number in one arbitrary vertex to 0 orleave all vertices unchanged. Now for each vertex Ilya wants to know the maximum possible beauty it can have.For each vertex the answer must be considered independently.The beauty of the root equals to number written on it.InputFirst line contains one integer number n — the number of vertices in tree (1 ≤ n ≤ 2·105).Next line contains n integer numbers ai (1 ≤ i ≤ n, 1 ≤ ai ≤ 2·105).Each of next n - 1 lines contains two integer numbers x and y (1 ≤ x, y ≤ n, x ≠ y),which means that there is an edge (x, y) in the tree.OutputOutput n numbers separated by spaces, where i-thnumber equals to maximum possible beauty of vertex i.Examplesinput
2
6 2
1 2
output
6 6
input
3
6 2 3
1 2
1 3
output
6 6 6
input
1
10
output
10
题目大意:有一个树,树上的每个点都有一个权值,对于一个点的魅力值来说,是他到根点1的路径上的所有点权值的最大公约数,对于每个路径上的点,你可以选择唯一点将他变为0或者不做改变,现在希望你让每个点都获得尽可能大的魅力值,输出每个点的魅力值
解题思路:这道题可以在dfs遍历的时候,若是某个权值被修改,一定是这个权值的因子过小,导致这个路径上的魅力值变小,那么我们就枚举当前点的因子,判断对于他的因子来说,是否在他之前的路径中出现次数大于等于深度-2,若是超过,则说明这个因子肯定会存在,那么就要这个因子,与x之前所有点gcd的值取max
深度-2的原因是,它意味着这个因子出现的次数仅仅在之前路径上的某一个权值中不存在,若是这个因子很大,那么我们就可以将这个权值变为0
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;typedef long long LL;vector<int> tu[200005];int b[200005],a[200005],check[200005],cnt[200005];int n;int gcd(int x, int y){if(y == 0) return x;else return gcd(y, x % y);}void dfs(int son,int fa,int deep){int i,flag;b[son]=gcd(a[son],b[fa]);check[son]=b[fa];for(i=1;i*i<=a[son];i++){if(a[son]%i==0){flag=i;if(cnt[flag]>=deep-2) check[son]=max(flag,check[son]);flag=a[son]/i;if(cnt[flag]>=deep-2) check[son]=max(flag,check[son]);if(i*i==a[son])cnt[i]++;elsecnt[i]++,cnt[a[son]/i]++;}}for(i=0;i<tu[son].size();i++){int k=tu[son][i];if(k==fa)continue;dfs(k,son,deep+1);}for(i=1;i*i<=a[son];i++){if(a[son]%i==0){if(i*i==a[son])cnt[i]--;elsecnt[i]--,cnt[a[son]/i]--;}}}int main(){int x,y,i;cin>>n;for(i=1;i<=n;i++) cin>>a[i];for(i=1;i<n;i++){cin>>x>>y;tu[x].push_back(y);tu[y].push_back(x);}dfs(1,0,1);for(i=1;i<=n;i++) cout<<check[i]<<" ";cout<<endl;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: