codeforces1101D.GCD Counting 數論+DP+dfs

D. GCD Counting

time limit per test

4.5 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given a tree consisting of nn vertices. A number is written on each vertex; the number on vertex ii is equal to aiai .

Let's denote the function g(x,y)g(x,y) as the greatest common divisor of the numbers written on the vertices belonging to the simple path from vertex xx to vertex yy (including these two vertices). Also let's denote dist(x,y)dist(x,y) as the number of vertices on the simple path between vertices xx and yy , including the endpoints. dist(x,x)=1dist(x,x)=1 for every vertex xx .

Your task is calculate the maximum value of dist(x,y)dist(x,y) among such pairs of vertices that g(x,y)>1g(x,y)>1 .

Input

The first line contains one integer nn — the number of vertices (1≤n≤2⋅105)(1≤n≤2⋅105) .

The second line contains nn integers a1a1 , a2a2 , ..., anan (1≤ai≤2⋅105)(1≤ai≤2⋅105) — the numbers written on vertices.

Then n−1n−1 lines follow, each containing two integers xx and yy (1≤x,y≤n,x≠y)(1≤x,y≤n,x≠y) denoting an edge connecting vertex xx with vertex yy . It is guaranteed that these edges form a tree.

Output

If there is no pair of vertices x,yx,y such that g(x,y)>1g(x,y)>1 , print 00 . Otherwise print the maximum value of dist(x,y)dist(x,y) among such pairs.

Examples

Input

Copy

3
2 3 4
1 2
2 3

Output

Copy

1

Input

Copy

3
2 3 4
1 3
2 3

Output

Copy

2

Input

Copy

3
1 1 1
1 2
2 3

Output

Copy

0

題意:給你一顆樹,每一個樹上有其權值,dist(x,y)爲兩點間的短距離,g(x,y)爲兩點間的gcd沒讓你求最長的dist(x,y)且g(x,y)>1.

思路:因爲要求的的是gcd大於1,所以只要有相同的不爲1的因子就可以滿足條件,所以我們就先把這每個點的權值的因子找出來,在樹上dfs,搜索當前根節點下的每個因子的dist,根據下一個節點相同因子的找最大值,一直取最大值。

代碼:

#include<stdio.h>
#include<string.h>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<iterator>
#include<set>
#include<map>
#include<bitset>
#include<complex>
#define ll long long
#define qq printf("QAQ\n");
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const double e=exp(1.0);
const double pi=acos(-1);
const double eps=1e-6;
int a[maxn],ans;
map<int,int>mp[maxn];
vector<int>fac[maxn];
void get_div(int x)
{
    int temp=a[x];
    for(int i=2;i*i<=temp;i++)
    {
        if(temp%i==0){
            fac[x].push_back(i);
            while(temp%i==0)temp/=i;
        }
    }
    if(temp!=1)fac[x].push_back(temp);
}
vector<int>v[maxn];
void dfs(int st,int fa)
{
    for(int i=0;i<fac[st].size();i++)//先每個點的每個因子初始化爲1
        mp[st][fac[st][i]]=1;
    for(int i=0;i<v[st].size();i++)
    {
        int next=v[st][i];
        if(next==fa)continue;
        dfs(next,st);
        for(int j=0;j<fac[st].size();j++)//遍歷每個節點的因子
        {
            int div=fac[st][j];
            mp[st][div]=max(mp[st][div],mp[next][div]+1);//最大長度
            ans=max(ans,mp[st][div]);
            for(int k=0;k<i;k++)
            {
                ans=max(ans,mp[next][div]+mp[v[st][k]][div]+1);//兩個分支 可以夠成最大的
            }
        }
    }
}
int main()
{
    int n,st,en;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        get_div(i);
    }
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&st,&en);
        v[st].push_back(en);
        v[en].push_back(st);
    }
    ans=0;
    dfs(1,-1);//因爲是把1這個因子不考慮,不用特判0 
    printf("%d\n",ans);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章