题意:
树形,每个节点有一个a[],求每个节点的beauty值:
把从根节点到这个节点经过的所有a[]收集起来,求他们的gcd。就是b值。
另外可以让某一个节点变为0,gcd(a,0)=a. gcd(0,a)=a;每次计算b值的时候都可以任意挑一个变为0,是独立的。
POINT:
利用set来保存当前节点的所有情况。 当前节点的情况可以由pre节点的情况全部推出来。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <set>
using namespace std;
#define LL long long
const int maxn = 2e5+10;
int a[maxn];
set<int>s[maxn];
set<int>::iterator it;
vector<int>G[maxn];
int gcd(int x,int y)
{
if(x<y) swap(x,y);
return y==0?x:gcd(y,x%y);
}
void dfs(int u,int pre,int now)//now就是什么都不变的情况
{
for(it=s[pre].begin();it!=s[pre].end();it++)
{
s[u].insert(gcd(*it,a[u]));//pre的情况加a[u]
}
// s[u].insert(now);//什么都不变的情况//这个不加的话,根节点的答案会错。
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(v==pre) continue;
s[v].insert(now);//把v变成0的情况。
dfs(v,u,gcd(now,a[v]));
}
}
int main()
{
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);
G[u].push_back(v);
G[v].push_back(u);
}
s[1].insert(0);//根变成0的情况
s[1].insert(a[1]);
dfs(1,0,a[1]);
for(int i=1;i<=n;i++)
{
if(i-1) printf(" ");
printf("%d",*s[i].rbegin());
}
printf("\n");
}