写法还是比较容易想到,但是这么暴力的写法不是那么的敢写。
就直接枚举了每一个点上面的点的所有的情况,对于这个点不放进去特判一下,然后排序去重提高效率。
注意dp[v]一开始存的是从根节点到这个节点都选的情况,这样才好往后转移。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 4e5 + 10;
typedef long long ll;
int dp[maxn], head[maxn], cnt = 0, a[maxn];
vector<int>vec[maxn];
struct node
{
int u, v, nxt;
node(int u=0,int v=0,int nxt=0):u(u),v(v),nxt(nxt){}
}ex[maxn];
void init()
{
memset(head, -1, sizeof(head));
cnt = 0;
}
void add(int u,int v)
{
ex[cnt] = node(u, v, head[u]);
head[u] = cnt++;
ex[cnt] = node(v, u, head[v]);
head[v] = cnt++;
}
int gcd(int a,int b)
{
return b == 0 ? a : gcd(b, a%b);
}
void dfs(int u,int pre)
{
for(int i=head[u];i!=-1;i=ex[i].nxt)
{
int v = ex[i].v;
if (v == pre) continue;
dp[v] = gcd(dp[u], a[v]);
vec[v].push_back(dp[u]);
for(int j=0;j<vec[u].size();j++) vec[v].push_back(gcd(vec[u][j], a[v]));
sort(vec[v].begin(), vec[v].end());
vec[v].erase(unique(vec[v].begin(), vec[v].end()), vec[v].end());
dfs(v, u);
}
}
int main()
{
init();
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i=1;i<n;i++)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
}
dp[1] = a[1];
vec[1].push_back(0);
dfs(1, -1);
for (int i = 1; i <= n; i++) dp[i] = max(dp[i], vec[i].back());
for (int i = 1; i <= n; i++) printf("%d ", dp[i]);
return 0;
}
