ABC248G
考虑枚举 GCD 的值为
直接求出有多少路径的 GCD 等于它不好求,我们考虑先求出满足 GCD 的值为
对于
前面的
与
然后就做完了,时间复杂度
#include<bits/stdc++.h>
using namespace std;
inline void dfs(int u,int tt){
cnt[u]=1; len[u]=1; res[u]=0; col[u]=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(!col[v]) continue;
dfs(v,tt);
res[u]=(res[u]+(1ll*cnt[u]*len[v]%mod+1ll*cnt[v]*len[u]%mod)%mod)%mod;
len[u]=(len[u]+len[v]+cnt[v])%mod;
cnt[u]=cnt[u]+cnt[v];
}
(ans[tt]+=res[u])%=mod;
}
int main(){
n=read();
for(int i=1;i<=n;i++){
int x=read(); m=max(m,x);
for(int j=1;j*j<=x;j++)
if(x%j==0){
g[j].emplace_back(i);
if(j*j<x) g[x/j].emplace_back(i);
}
}
for(int i=1;i<n;i++){
int u=read(),v=read();
add(u,v); add(v,u);
}
for(int i=m;i;i--){
if(g[i].empty()) continue;
for(int j=0;j<g[i].size();j++) col[g[i][j]]=1;
for(int j=0;j<g[i].size();j++) if(col[g[i][j]]) dfs(g[i][j],i);
for(int j=i+i;j<=m;j+=i) (ans[i]+=mod-ans[j])%=mod;
}
for(int i=1;i<=m;i++) (sum+=1ll*ans[i]*i%mod)%=mod;
printf("%d\n",sum);
return 0;
}