因为我太菜了,于是乎就找了份代码,理解了一下思路(把坑填完才能好好复习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; }