Codeforces Round #430 (Div. 2) C. Ilya And The Tree(dfs+因子+树)

C. Ilya And The Tree
time limit per test 2 seconds
memory limit per test 256 megabytes
input standard input
output standard output
Ilya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very interesting tree rooted at vertex 1. There is 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 from the root to x, including this vertex itself. In addition, Ilya can change the number in one arbitrary vertex to 0 or leave 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.

Input
First 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.

Output
Output n numbers separated by spaces, where i-th number equals to maximum possible beauty of vertex i.

Examples
input
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]++;
			else
				cnt[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]--;
			else
				cnt[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;
}

猜你喜欢

转载自blog.csdn.net/c_czl/article/details/85273702
今日推荐