社区讨论

WA on test 9...

CF809ESurprise me!参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo95u6k7
此快照首次捕获于
2023/10/28 06:03
2 年前
此快照最后确认于
2023/10/28 06:03
2 年前
查看原帖
蒟蒻调不动了/ll
球球了。
CPP
#include <bits/stdc++.h>



using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
const int Mod = 1e9 + 7;
int n, m, a[N], Ref[N];
int first[N], nex[N << 1], v[N << 1], num = 0;
int stu[N], top = 0, sta[N], b[N], rec[N], tot = 0, Rec = 0;
int phi[N], pri[N], mu[N], vis[N], cnt = 0;
int dep[N], f[N][21], dfn[N], in = 0;
ll dp[N], ans = 0, F[N], g[N], sum = 0, siz[N]; 
vector<int> G[N];
inline void add(int x, int y) {
	v[++num] = y;
	nex[num] = first[x];
	first[x] = num;
}
inline void Pre(int n) {
	phi[1] = mu[1] = 1;
	for (int i = 2; i <= n; i++) {
		if (!vis[i]) {
			pri[++cnt] = i;
			mu[i] = -1, phi[i] = i - 1;
		}
		for (int j = 1; j <= cnt && 1ll * pri[j] * i <= n; j++) {
			vis[pri[j] * i] = true;
			if (i % pri[j]) {
				mu[i * pri[j]] = -mu[i];
				phi[i * pri[j]] = phi[i] * phi[pri[j]];
			} else {
				mu[i * pri[j]] = 0;
				phi[i * pri[j]] = phi[i] * pri[j];
				break;
			}
		}
	}
}
inline void pre(int u, int fa) {
	dfn[u] = ++in;
	dep[u] = dep[fa] + 1; f[u][0] = fa;
	for (int i = 1; i <= 20; i++) f[u][i] = f[f[u][i - 1]][i - 1];
	for (int i = first[u]; i != -1; i = nex[i]) {
		int to = v[i];
		if (to != fa) {
			pre(to, u);
		}
	}
}
inline int Lca(int x, int y) {
	if (dep[x] < dep[y]) swap(x, y);
	for (int i = 20; i >= 0; i--) if (dep[f[x][i]] >= dep[y]) x = f[x][i];
	if (x == y) return  x;
	for (int i = 20; i >= 0; i--) if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
	return f[x][0];
}
inline bool cmp(int x, int y) {
	return dfn[x] < dfn[y];
}
inline void dfs(int u) {
	ll tem = 0; siz[u] = 0;
	if (sta[u]) (ans += 2 * phi[a[u]] % Mod * sum % Mod * dep[u] % Mod), siz[u] = phi[a[u]];
	if (sta[u]) (ans += Mod - 2 * phi[a[u]] * phi[a[u]] % Mod * dep[u] % Mod) %= Mod;
	for (int i = 0; i < G[u].size(); i++) {
		int to = G[u][i];
		dfs(to);
		ans = (ans + Mod - 4 * dep[u] % Mod * siz[to] % Mod * tem % Mod) % Mod;
		if (sta[u]) (ans += Mod - 4 * dep[u] % Mod * siz[to] % Mod * phi[a[u]] % Mod) %= Mod;
		(siz[u] += siz[to]) %= Mod;
		(tem += siz[to]) %= Mod;
	}
}
inline ll exp(ll a, ll b) {
	ll res = 1;
	while (b) {
		if (b & 1) {
			res = res * a % Mod;
		}
		a = a * a % Mod;
		b >>= 1;
	}
	return res;
}
int main() { 
	memset(first, -1, sizeof first);
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n;
	Pre(n);
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		Ref[a[i]] = i;
	}
	for (int i = 1; i < n; i++) {
		int x, y;
		cin >> x >> y;
		add(x, y);
		add(y, x);
	}
	pre(1, 0);
	for (int i = 1; i <= n; i++) {
		Rec = 0, tot = 0, top = 0, sum = 0;
		ans = 0;
		for (int j = i; j <= n; j += i) {
			rec[++Rec] = Ref[j];
			(sum += phi[j]) %= Mod;
		}
		sort(rec + 1, rec + Rec + 1, cmp);
		stu[++top] = 1, b[++tot] = 1;
		for (int j = 1; j <= Rec; j++) {
			sta[rec[j]] = true;
			if (rec[j] == 1) continue;
			int lca = Lca(stu[top], rec[j]);
			if (lca != stu[top]) {
				while (dfn[stu[top - 1]] > dfn[lca]) {
					G[stu[top - 1]].push_back(stu[top]);
					top--;
				}
				if (stu[top - 1] != lca) {
					G[lca].push_back(stu[top]);
					b[++tot] = lca;
					stu[top] = lca;
				} else {
					G[stu[top - 1]].push_back(stu[top]);
					top--;
				}
			}
			b[++tot] = rec[j];
			stu[++top] = rec[j];
		}
		for (int j = 1; j < top; j++) G[stu[j]].push_back(stu[j + 1]);
		dfs(1);
		F[i] = ans;
		for (int j = 1; j <= tot; j++) G[b[j]].clear();
		for (int j = 1; j <= Rec; j++) sta[rec[j]] = 0; 
	}
	for (int i = 1; i <= n; i++) {
		for (int j = i; j <= n; j += i) {
			(g[i] += F[j] * mu[j / i]);
			if (g[i] >= Mod) g[i] -= Mod;
			if (g[i] < 0) g[i] += Mod;
		}
	}
	ans = 0;
	for (int i = 1; i <= n; i++) {
		(ans += i * exp(phi[i], Mod - 2) % Mod * g[i] % Mod) %= Mod;
	}
	cout << ans * exp(n, Mod - 2) % Mod * exp(n - 1, Mod - 2) % Mod << '\n';
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...