Codeforces 1230E - Kamil and Making a Stream (暴力,数学)

Description

思路

这E题有点暴力
由于不同的gcd(u, v)的个数不会超过\(log_2V\),V是树上最大的数,所以每个结点开个数组,保存从根节点到该节点的所有gcd值。暴力搞就好了。

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int N = 1e5 + 10;
const int M = 1e9 + 7;
 
map<int, map<ll, int>> ds;
ll val[N];
vector<int> np[N];
ll ans = 0;
 
ll gcd(ll a, ll b) {
    if(b == 0) return a;
    return gcd(b, a%b);
 
}
 
void dfs(int p, int fa) {
    ds[p][val[p]] = 1;
    if(p != 1)
        for(auto par : ds[fa]) {
            ll g = gcd(par.first, val[p]);
            ans = (ans + g * par.second) % M;
            if(ds[p].count(g)) ds[p][g] += par.second;
            else ds[p][g] = par.second;
        }
    ans = (ans + val[p]) % M;
    for(int nt : np[p]) {
        if(nt == fa) continue;
        dfs(nt, p);
    }
}
 
int main() {
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> val[i];
    }
    for(int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        np[u].push_back(v);
        np[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
}
posted @ 2020-04-14 23:01  limil  阅读(94)  评论(0编辑  收藏  举报