这道题比较水吧,也没啥好说的
首先,两个数如果有 (geq1) 的公因数,则他们一定有公共质因数
然后对每个数质因数分解
之后 (dfs) 更新就可以了
设状态为 (f[u][i]) , 表示 (u) 节点向下,以 (a[u]) 的第 (i) 个质因数为公因数,向下的深度
先更新 (ans) :
[ans=max(ans,f[u][k]+f[v][j]);
]
再更新 (f[u][k])
[f[u][k]=max(f[u][k],f[v][j]+1);
]
同时为了分解质因数快一点,我们可以先把质数筛出来(懒得打欧拉筛,就用埃氏筛凑合吧,反正数据不大)
代码
#include<bits/stdc++.h>
namespace my_std
{
using namespace std;
#define R register
#define rep(i,a,b) for (R int i=(a);i<=(b);i++)
#define drep(i,a,b) for (R int i=(a);i>=(b);i--)
#define go(u) for (R int i=head[(u)];i;i=e[i].nxt)
#define pf printf
#define writeln(x) write(x),putchar('
')
#define writesp(x) write(x),putchar(' ')
#define mem(x,v) memset(x,v,sizeof(x))
typedef long long ll;
const int INF=0x7fffffff;
inline int read()
{
int sum=0,f=0;
char c=getchar();
while (!isdigit(c))
{
f|=(c=='-');
c=getchar();
}
while (isdigit(c))
{
sum=(sum<<1)+(sum<<3)+(c^48);
c=getchar();
}
return f?-sum:sum;
}
void write(int k)
{
if (k<0) putchar('-'),k=-k;
if (k>=10) write(k/10);
putchar(k%10+'0');
}
inline void chkmax(int &x,int y)
{
if (x<y) x=y;
}
inline void chkmin(int &x,int y)
{
if (x>y) x=y;
}
#define templ template<typename T>
}
using namespace my_std;
const int N=1000010;
int n,ans,cnt,flag,a[N],head[N],f[N][15];
int top,prime[N],isprime[N];
struct edge
{
int to,nxt;
}e[N<<1];
vector<int>G[N];
inline void add(int u,int v)
{
e[++cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt;
}
inline void get_prime(int n)
{
mem(isprime,1);
isprime[0]=isprime[1]=0;
rep(i,2,n) if (isprime[i])
{
prime[++top]=i;
for (int j=i<<1;j<=n;j+=i)
{
isprime[j]=0;
}
}
}
inline void split(int u)
{
int x=a[u];
rep(i,1,top) if (x%prime[i]==0)
{
G[u].push_back(prime[i]);
while (x%prime[i]==0) x/=prime[i];
}
if (x!=1) G[u].push_back(x);
}
void dfs(int u,int fa)
{
if (G[u].size()>=1) rep(i,0,G[u].size()-1) f[u][i]=1;
go(u)
{
int v=e[i].to;
if (v==fa) continue;
dfs(v,u);
if (G[u].size()>=1) rep(k,0,G[u].size()-1) if (G[v].size()>=1) rep(j,0,G[v].size()-1) if (G[u][k]==G[v][j])
{
chkmax(ans,f[u][k]+f[v][j]);
chkmax(f[u][k],f[v][j]+1);
}
}
}
int main()
{
n=read();
get_prime(sqrt(200000));
rep(i,1,n) a[i]=read(),flag|=(a[i]>1);
if (!flag)
{
writeln(0);
return 0;
}
rep(i,1,n-1)
{
int u=read(),v=read();
add(u,v),add(v,u);
}
ans=1;
rep(i,1,n) split(i);
dfs(1,0);
writeln(ans);
return 0;
}