题解:
对于每个
i
i
i,处理出:
f
i
=
∑
a
∑
b
[
(
v
a
l
a
,
v
a
l
b
)
=
=
i
]
φ
(
v
a
l
a
)
φ
(
v
a
l
b
)
d
i
s
(
a
,
b
)
f_i=\sum_a\sum_b[(val_a,val_b)==i]\varphi(val_a)\varphi(val_b)dis(a,b)
fi=a∑b∑[(vala,valb)==i]φ(vala)φ(valb)dis(a,b)
那么 a n s = ∑ i f i i φ ( i ) ans = \sum_i\frac{f_i i}{\varphi(i)} ans=i∑φ(i)fii
先处理一个
g
g
g:
g
i
=
∑
i
∣
v
a
l
a
∑
i
∣
v
a
l
b
φ
(
a
)
φ
(
b
)
d
i
s
(
a
,
b
)
g_i = \sum_{i|val_a}\sum_{i|val_b}\varphi(a)\varphi(b)dis(a,b)
gi=i∣vala∑i∣valb∑φ(a)φ(b)dis(a,b)
这个可以点分治中枚举一下因数,时间复杂度
O
(
n
log
2
n
)
O(n\log^2n)
O(nlog2n)。
那么显然
g
n
=
∑
n
∣
d
f
d
g_n = \sum_{n|d}f_d
gn=n∣d∑fd
Mobius反演一下就行了,时间复杂度 O ( n log n ) O(n \log n) O(nlogn)。
#include <bits/stdc++.h>
using namespace std;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
char ch=nc(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
const int N=2e5+50, mod=1e9+7;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y);}
inline int mul(int x,int y) {return (long long)x*y%mod;}
inline int power(int a,int b,int rs=1) {for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a); return rs;}
int n,pr[N],npr[N],pt;
int mu[N],phi[N];
int val[N],s[2][N];
int vis[N],sze[N],mx,total,G;
int f[N],h[N];
vector <int> g[N];
vector <int> edge[N];
inline void sieve() {
mu[1]=phi[1]=1;
for(int i=2;i<=n;i++) {
if(!npr[i]) {pr[++pt]=i; mu[i]=mod-1; phi[i]=i-1;}
for(int j=1;j<=pt;j++) {
int k=i*pr[j];
if(k>n) break;
npr[k]=1;
if(i%pr[j]) {
mu[k]=mod-mu[i];
phi[k]=mul(phi[i],pr[j]-1);
} else {
mu[k]=0;
phi[k]=phi[i]*pr[j];
break;
}
}
}
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j+=i) g[j].push_back(i);
}
inline void calcG(int x,int f) {
sze[x]=1; int mx_son=0;
for(auto v:edge[x]) if(!vis[v] && v^f) {
calcG(v,x); sze[x]+=sze[v];
mx_son=max(mx_son,sze[v]);
} mx_son=max(mx_son,total-sze[x]);
if(mx>=mx_son) mx=mx_son, G=x;
}
inline int add(int x,int d,int t) {
int v1=phi[x], v2=mul(phi[x],d);
for(auto v:g[x])
s[0][v]=add(s[0][v],mul(v1,t)), s[1][v]=add(s[1][v],mul(v2,t));
}
inline void ask(int x,int d) {
int v1=phi[x], v2=mul(phi[x],d);
for(auto v:g[x])
f[v]=add(f[v],mul(s[0][v],v2)), f[v]=add(f[v],mul(s[1][v],v1));
}
inline void dfs1(int x,int d,int f) {
ask(val[x],d); sze[x]=1;
for(auto v:edge[x])
if(!vis[v] && v^f)
dfs1(v,d+1,x), sze[x]+=sze[v];
}
inline void dfs2(int x,int d,int flag,int f) {
add(val[x],d,flag);
for(auto v:edge[x])
if(!vis[v] && v^f)
dfs2(v,d+1,flag,x);
}
inline void solve(int x) {
add(val[x],0,1);
vis[x]=1;
for(auto v:edge[x])
if(!vis[v]) {
dfs1(v,1,x);
dfs2(v,1,1,x);
}
for(auto v:edge[x])
if(!vis[v])
dfs2(v,1,mod-1,x);
add(val[x],0,mod-1);
for(auto v:edge[x])
if(!vis[v]) {
mx=total=sze[v];
calcG(v,x);
solve(G);
}
}
int main() {
n=rd(); sieve();
for(int i=1;i<=n;i++) val[i]=rd();
for(int i=1;i<n;i++) {
int x=rd(), y=rd();
edge[x].push_back(y);
edge[y].push_back(x);
}
mx=total=n;
calcG(1,0);
solve(G);
for(int i=n;i>=1;i--)
for(int j=i;j<=n;j+=i)
h[i]=add(h[i],mul(f[j],mu[j/i]));
int ans=0;
for(int i=1;i<=n;i++)
ans=add(ans,mul(h[i],mul(i,power(phi[i],mod-2))));
cout<<mul(ans,power(1ll*n*(n-1)/2%mod,mod-2))<<'\n';
}