1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| #include <bits/stdc++.h> #define pb push_back using namespace std; typedef long long ll; const int N = 200010, mod = 1e9 + 7; int n, a[N], id[N], inv[N], ans = 0; int p[N], mu[N], phi[N], lp; bool pri[N]; vector<int> e[N], E[N]; int fa[N], sz[N], son[N], dep[N], top[N], dfn[N], idx = 0; int s[N], f[N], g[N], ss[N]; int pp[N], len, sta[N], Top = 0; bool flag[N];
inline int add(const int &x, const int &y) { return x + y < mod ? x + y : x + y - mod; } inline int sub(const int &x, const int &y) { return x - y < 0 ? x - y + mod : x - y; } inline int mul(const int &x, const int &y) { return (int)((ll)x * y % mod); } inline bool cmp(const int &x, const int &y) { return dfn[x] < dfn[y]; } void Sieve() { inv[0] = inv[1] = 1, phi[1] = mu[1] = 1; for(int i = 2; i <= n; i++) inv[i] = mul(mod - mod / i, inv[mod % i]); for(int i = 2; i <= n; i++) { if(!pri[i]) p[++lp] = i, mu[i] = mod - 1, phi[i] = i - 1; for(int j = 1; p[j] * i <= n; j++) { pri[p[j] * i] = 1; if(i % p[j] == 0) { phi[p[j] * i] = phi[i] * p[j]; break; } mu[p[j] * i] = sub(0, mu[i]); phi[p[j] * i] = phi[i] * (p[j] - 1); } } for(int i = 1; i <= n; i++) for(int j = i; j <= n; j += i) s[j] = add(s[j], mul(mul(i, mu[j / i]), inv[phi[i]])); } void dfs1(int u, int ff) { fa[u] = ff, dep[u] = dep[ff] + 1, sz[u] = 1; for(auto v : e[u]) if(v ^ ff) { dfs1(v, u), sz[u] += sz[v]; if(sz[son[u]] < sz[v]) son[u] = v; } } void dfs2(int u, int tp) { top[u] = tp, dfn[u] = ++idx; if(son[u]) dfs2(son[u], tp); for(auto v : e[u]) if(!top[v]) dfs2(v, v); } int LCA(int x, int y) { for(; top[x] != top[y]; x = fa[top[x]]) if(dep[top[x]] < dep[top[y]]) swap(x, y); return dep[x] < dep[y] ? x : y; } void insert(int x) { int lca = LCA(x, sta[Top]); if(Top == 1 || lca == sta[Top]) { sta[++Top] = x; return ; } for(; Top > 1 && dfn[sta[Top - 1]] >= dfn[lca]; --Top) E[sta[Top - 1]].pb(sta[Top]); if(lca != sta[Top]) E[lca].pb(sta[Top]), sta[Top] = lca; sta[++Top] = x; } void dp(int u) { ss[u] = flag[u] * phi[a[u]], f[u] = g[u] = 0; for(auto v : E[u]) { dp(v); int w = dep[v] - dep[u]; g[u] = add(g[v], add(add(g[u], mul(ss[v], add(mul(w, ss[u]), f[u]))), mul(ss[u], f[v]))); ss[u] = add(ss[u], ss[v]), f[u] = add(f[u], add(f[v], mul(ss[v], w))); } E[u].clear(), flag[u] = 0; } int calc(int x) { len = 0; for(int i = x; i <= n; i += x) pp[++len] = id[i]; sort(pp + 1, pp + len + 1, cmp), sta[Top = 1] = 1; for(int i = 1; i <= len; i++) { flag[pp[i]] = 1; if(pp[i] != 1) insert(pp[i]); } for(; Top > 1; --Top) E[sta[Top - 1]].pb(sta[Top]); dp(1); return g[1]; } int main() { scanf("%d", &n), Sieve(); for(int i = 1; i <= n; i++) scanf("%d", &a[i]), id[a[i]] = i; for(int i = 1, x, y; i < n; i++) scanf("%d%d", &x, &y), e[x].pb(y), e[y].pb(x); dfs1(1, 0), dfs2(1, 1); for(int i = 1; i <= n; i++) ans = add(ans, mul(calc(i), s[i])); printf("%d\n", mul(add(ans, ans), mul(inv[n], inv[n - 1]))); return 0; }
|