1. 程式人生 > >Ilya And The Tree 【樹上DFS】

Ilya And The Tree 【樹上DFS】

C. Ilya And The Tree

time limit per test2 seconds

memory limit per test256 megabytes

Ilya is very fond of graphs, especially trees. During his lasttrip to the forest Ilya found a very interesting tree rooted at vertex 1. There is an integer number written oneach vertex of the tree; the number written on vertex

i is equal to ai.

Ilya believes that the beauty of the vertexx is the greatest common divisor of allnumbers written on the vertices on the path from the root tox, including this vertex itself. Inaddition, Ilya can change the number in one arbitrary vertex to0 or leave all vertices unchanged. Nowfor 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 numbern — the number of vertices in tree(1 ≤ n ≤ 2·105).

Next line containsn 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 possiblebeauty 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


【題意】

給出一棵生成樹,每個節點都有一個值,現在要求出每個節點的美麗值的最大值,美麗值的定義為從根節點到該節點(包含)路徑上所有點的值的gcd,求解每個點時可以把路徑上某一個點的值變為0。你可以認為每個點美麗值的求解是獨立的。

【思路】

顯然,我們可以進行樹上DFS。

我們用dp陣列來儲存每個節點在路徑上沒有改變值的時候的gcd,然後先單獨考慮當前點不選的美麗值即dp[u]。然後用vector[u]陣列來儲存節點v的父親節點的美麗值的所有可能情況,這裡的情況有可能是改變了值後的,也可能沒有,但由於我們在這一步一定會算入節點v的值(不算的情況單獨考慮),所以滿足最多隻改變一次值的要求。

每次更新完後去重一下,提高時間效率以及避免超記憶體等等。

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))

typedef long long ll;
const int maxn = 200005;
const ll mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;

int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}

int n,cnt;
int a[maxn],dp[maxn];
int head[maxn];
vector<int>vec[maxn];

struct node
{
    int v,next;
}e[maxn*2];

void add(int u,int v)
{
    e[cnt].v=v;
    e[cnt].next=head[u];
    head[u]=cnt++;
}

void dfs(int u,int pre)
{
    for(int i=head[u];~i;i=e[i].next)
    {
        int v=e[i].v;
        if(v==pre) continue;
        dp[v]=gcd(dp[u],a[v]);
        vec[v].push_back(dp[u]);   //不改變當前節點值的情況
        for(int i=0;i<vec[u].size();i++)
        {
            vec[v].push_back(gcd(vec[u][i],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()
{
    mst(head,-1);
    cnt=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    int x,y;
    for(int i=0;i<n-1;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    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]);
    }
    printf("%d\n",dp[n]);
}