因为我太菜了,于是乎就找了份代码,理解了一下思路(把坑填完才能好好复习zz
思路:
- 1.先用筛求质数表,表长大约是sqrt(1e9)
- 2.建树
- 3.对权值进行质因数分解,并把对应的权值下标与素数对应起来存下来
- 4.然后树形dp求符合条件的最长链
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=31624;
struct node{
int v,nex;
}t[N<<1];
int val[N][10],tot[N];
int zhi[M],e,dp[N][10];
int las[N],len;bool f[M];
inline void add(int u,int v){
t[++len]=(node){v,las[u]},las[u]=len;
}
inline void sai(int maxe){
for(int i=2;i<=maxe;++i){
if(!f[i])zhi[++e]=i;
for(int j=1;j<=e;++j){
if(i*zhi[j]>maxe)break;
f[i*zhi[j]]=1;
if(i%zhi[j]==0)break;
}
}
}
int ans=1;
inline void dfs(int x,int fa){
for(int i=1;i<=tot[x];++i){
dp[x][i]=1;
}
for(int i=las[x];i;i=t[i].nex){
int v=t[i].v;
if(v!=fa){
dfs(v,x);
for(int j=1;j<=tot[x];++j){
for(int k=1;k<=tot[v];++k){
if(val[x][j]==val[v][k]){
ans=max(ans,dp[x][j]+dp[v][k]);
dp[x][j]=max(dp[x][j],dp[v][k]+1);
}
}
}
}
}
}
int main(){
sai(M-1);
//每个点最多由9个不同质数
int n;
scanf("%d",&n);
for(int i=1;i<n;++i){
int u,v;
scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
for(int i=1;i<=n;++i){
int x;
scanf("%d",&x);
for(int j=1;j<=e;++j){
if(x<zhi[j])break;
if(x%zhi[j]==0){
val[i][++tot[i]]=zhi[j];
while(x%zhi[j]==0)x/=zhi[j];
}
}
if(x>1){
val[i][++tot[i]]=x;
}
}
dfs(1,1);
printf("%d",ans);
return 0;
}
京公网安备 11010502036488号