cf1210 C. Kamil and Making a Stream
题意:
一棵有点权的树,定义路径的值为路径上所有点取 gcd。
只考虑祖先-后代路径(即路上每个点的深度不同,不考虑那种v形的),求所有路径的值之和,取模。
点权范围 1e12
思路:
一条链上,从上往下取一路取 gcd,最多会产生 \(log(链头的值)\le log(1e12)<40\) 个不同的值
map 暴力记录父亲传下来的所有数的集合
注意取模会影响 gcd,别取模
void dfs(int u, int fa, map<ll,ll> pre) {
pre[a[u]]++;
map<ll,ll> now;
for(auto &[x, cnt] : pre) {
ll y = __gcd(x, a[u]);
(ans += cnt * y) %= mod;
now[y] += cnt;
}
for(int v : G[u]) if(v != fa)
dfs(v, u, now);
}
signed main() {
iofast;
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i < n; i++) {
int u, v; cin >> u >> v;
G[u].pb(v), G[v].pb(u);
}
dfs(1, 0, map<ll,ll>());
cout << ans;
}

浙公网安备 33010602011771号