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;
}
posted @ 2022-04-17 11:59  Bellala  阅读(88)  评论(0)    收藏  举报