题目分析:
蛮简单的一道题,对于每个数拆质因子,对于每个质因子找出最长链,在每个地方枚举一下拼接
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 205000; 5 6 int n,a[maxn],prime[maxn],flag[maxn],minn[maxn],num,ans; 7 vector <int> g[maxn]; 8 vector <pair<int,int> > mp[maxn]; 9 10 vector<int> cl[maxn]; 11 12 void getprime(int N){ 13 for(int i=2;i<=N;i++){ 14 if(!flag[i]){prime[++num] = i,minn[i] = i;} 15 for(int j=1;j<=num&&i*prime[j]<=N;j++){ 16 flag[i*prime[j]] = 1; 17 minn[i*prime[j]] = prime[j]; 18 if(i%prime[j] == 0) break; 19 } 20 } 21 } 22 23 void read(){ 24 scanf("%d",&n); 25 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 26 for(int i=1;i<n;i++){ 27 int u,v; scanf("%d%d",&u,&v); 28 g[u].push_back(v); g[v].push_back(u); 29 } 30 } 31 32 void dp(int now,int fa){ 33 for(int i=0;i<g[now].size();i++){ 34 if(g[now][i] == fa) continue; 35 dp(g[now][i],now); 36 } 37 int p = a[now]; 38 while(p != 1){cl[minn[p]].clear(); p /= minn[p]; } 39 for(int i=0;i<g[now].size();i++){ 40 if(g[now][i] == fa) continue; 41 for(int j=0;j<mp[g[now][i]].size();j++){ 42 if(a[now] % mp[g[now][i]][j].first == 0){ 43 cl[mp[g[now][i]][j].first].push_back(mp[g[now][i]][j].second); 44 } 45 } 46 } 47 p = a[now]; 48 while(p != 1){ 49 int z = minn[p]; while(p%z == 0) p /= z; 50 int maxx = 0,sec = 0; 51 for(int i=0;i<cl[z].size();i++){ 52 if(cl[z][i] >= maxx) sec = maxx,maxx = cl[z][i]; 53 else if(cl[z][i] > sec) sec = cl[z][i]; 54 } 55 mp[now].push_back(make_pair(z,maxx+1)); 56 ans = max(ans,maxx+sec+1); 57 } 58 } 59 60 void work(){ 61 getprime(200000); 62 dp(1,0); 63 printf("%d ",ans); 64 } 65 66 int main(){ 67 read(); 68 work(); 69 return 0; 70 }