educational codeforces round 58 (div2) D. GCD Counting
阿新 • • 發佈:2019-01-13
這道題每個節點都由子節點的不同狀態轉移過來,只要子節點可以整除這個節點的的某個質因子,就可以轉移。為了遍歷找到本節點的質因子對應於這個節點子節點的哪些狀態,需要開個map<pair<int,int> ,int>來儲存
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> P; vector<int> G[200001]; vector<int> vec[200001]; int dp[200001][10]; int a[200001]; int ans; map<P,int> mp; void dfs(int rt,int fa) { int max1[10],max2[10]; memset(max1,0,sizeof(max1)); memset(max2,0,sizeof(max2)); for(int i=0;i<vec[rt].size();i++) { int to=vec[rt][i]; if(to==fa) continue; dfs(to,rt); for(int j=0;j<G[rt].size();j++) {int num=G[rt][j]; if(a[to]%num==0) { int pos=mp[P(num,to)]; int tmp=dp[to][pos]; if(tmp>max1[j]) { max2[j]=max1[j]; max1[j]=tmp; } else if(tmp>max2[j]) { max2[j]=tmp; } } } } for(int i=0;i<G[rt].size();i++) { dp[rt][i]=1+max1[i]; ans=max(ans,max1[i]+max2[i]+1); } } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=1;i<=n;i++) { int k=a[i]; for(int j=2;j*j<=k;j++) { if(k%j==0) { G[i].push_back(j); mp[P(j,i)]=G[i].size()-1; while(k%j==0) k/=j; } } if(k>1) { G[i].push_back(k); mp[P(k,i)]=G[i].size()-1; } } for(int i=1;i<=n-1;i++) { int x,y; scanf("%d%d",&x,&y); vec[x].push_back(y); vec[y].push_back(x); } dfs(1,-1); printf("%d\n",ans); }