题解:
对于每个
,处理出:
那么
先处理一个
:
这个可以点分治中枚举一下因数,时间复杂度
。
那么显然
Mobius反演一下就行了,时间复杂度 。
#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';
}