cf 990G - GCD Counting
#include<bits/stdc++.h> #define t 200000 #define MAXN 200100 using namespace std; int n; int fa[MAXN],fa1[MAXN]; long long ans[MAXN],size[MAXN]; vector <int> e[MAXN],Edge[MAXN]; int find(int x){ if (x==fa1[x]) return fa1[x]; else return fa1[x]=find(fa1[x]); } void dfs(int x,int y){ int x1,x2; x1=Edge[x].size(); for (int i=0;i<x1;i++){ x2=Edge[x][i]; if(x2==y) continue; fa[x2]=x; dfs(x2,x); } } int main(){ scanf("%d",&n); int x,y; for (int i=1;i<=n;i++){ scanf("%d",&x); e[x].push_back(i); } for (int i=1;i<=n-1;i++){ scanf("%d %d",&x,&y); Edge[x].push_back(y); Edge[y].push_back(x); } dfs(1,-1); for (int i=1;i<=t;i++){ for (int j=i;j<=t;j+=i){ ans[i]+=e[j].size(); x=e[j].size(); for (int k=0;k<x;k++){ int y=e[j][k]; fa1[y]=y; size[y]=1; } } for (int j=i;j<=t;j+=i){ x=e[j].size(); for (int k=0;k<x;k++){ int y=e[j][k]; if (y==1) continue; if (fa1[fa[y]]==0) continue; int x1=find(y); int y1=find(fa[y]); ans[i]=ans[i]+size[x1]*size[y1]; fa1[x1]=y1; size[y1]+=size[x1]; } } for (int j=i;j<=t;j+=i){ x=e[j].size(); for (int k=0;k<x;k++){ int y=e[j][k]; fa1[y]=0; size[y]=0; } } } for (int i=t;i>=1;i--) for (int j=i*2;j<=t;j+=i) ans[i]-=ans[j]; for (int i=1;i<=t;i++) if (ans[i]) printf("%d %lld\n",i,ans[i]); return 0; }