GCD Counting
提供一个非常容易的做法。
还是考虑点分治,但不用莫反,也不用容斥。
考虑找出重心后深搜,找到每个点到重心的路径的点权
这看起来很暴力,其实是个经典套路。由于
由于限时比较大,所以没有什么压力,复杂度应该是大约是三只
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <numeric>
#include <vector>
#include <unordered_map>
#include <unordered_set>
using namespace std;
const int N = 2e5 + 5;
int n, a[N];
vector<int> G[N];
bool del[N];
unordered_map<int, int> cnt, tcnt;
unordered_set<int> st, tst;
int wc, tot;
int sz[N];
long long ans[N];
void dfs_sz(int u, int fa)
{
sz[u] = 0;
if (del[u]) return;
sz[u] = 1;
for (auto& j : G[u])
{
if (j != fa)
{
dfs_sz(j, u);
sz[u] += sz[j];
}
}
}
void dfs_wc(int u, int fa)
{
if (del[u]) return;
int maxn = tot - sz[u];
for (auto& j : G[u])
{
if (j != fa)
{
dfs_wc(j, u);
maxn = max(maxn, sz[j]);
}
}
if (maxn <= tot / 2) wc = u;
}
int dis[N];
void dfs_dis(int u, int d, int fa)
{
if (del[u]) return;
dis[u] = gcd(d, a[u]);
ans[dis[u]]++;
cnt[dis[u]]++;
tcnt[dis[u]]++;
tst.insert(dis[u]);
st.insert(dis[u]);
for (auto& j : G[u])
{
if (j != fa) dfs_dis(j, dis[u], u);
}
}
void calc(int u)
{
if (del[u]) return;
cnt.clear();
st.clear();
wc = 0;
tot = 0;
dfs_sz(u, 0);
tot = sz[u];
dfs_wc(u, 0);
u = wc;
del[u] = 1;
tcnt.clear();
tst.clear();
for (auto& j : G[u])
{
cnt.clear();
st.clear();
dfs_dis(j, a[u], u);
for (auto& k1 : st)
{
for (auto& k2 : st)
{
if (k2 < k1) continue;
if (k1 == k2)
{
ans[k1] -= (1LL * cnt[k1] * (cnt[k1] - 1LL) / 2LL);
}
else
{
ans[gcd(k1, k2)] -= (1LL * cnt[k1] * cnt[k2]);
}
}
}
}
for (auto& k1 : tst)
{
for (auto& k2 : tst)
{
if (k2 < k1) continue;
if (k1 == k2)
{
ans[k1] += (1LL * tcnt[k1] * (tcnt[k1] - 1LL) / 2);
}
else
{
ans[gcd(k1, k2)] += (1LL * tcnt[k1] * tcnt[k2]);
}
}
}
//cout << "\n\n";
for (auto& j : G[u])
{
calc(j);
}
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
ans[a[i]]++;
}
for (int i = 1; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].emplace_back(v);
G[v].emplace_back(u);
}
calc(1);
for (int i = 1; i <= 200000; i++)
{
if (ans[i])
{
printf("%d %lld\n", i, ans[i]);
}
}
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现