Codeforces Round # 588 (Div. 2) -E. Kamil and Making a Stream- seeking gcd between trees and the same diameter at both the two nodes

Codeforces Round # 588 (Div. 2) -E. Kamil and Making a Stream- seeking gcd between trees and the same diameter at both the two nodes


【Problem Description】

Give you a tree, the tree each node has a weight. Defined \ (1 \ sim v \) of all the nodes through which the shortest path \ (U \) called \ (V \) ancestor node. Defined function \ (F (U, V) = GCD (U, T1, T2, \ DOTS, V) \) , where \ (u, t1, t2, \ dots \) are \ (V \) of ancestors. Seeking \ (\ SUM f (U, v) \) .

【Solution】

For each node \ (v \) to maintain a \ (vector \) array, which records all of its ancestors \ (u \) to \ (v \) is \ (f (u, v) \) values, and \ (f (u, v) \ ) the number of occurrences. Then for node \ (v \) son node \ (S \) , all its \ (f (u, s) \) values for all his \ (f (u, v) \) values and \ (a [s] \) a \ (GCD \) . Contribution to the total answer, as long as the value is multiplied by the number of times you can appear. (In fact, the practice is very violent)


【Code】

#include <bits/stdc++.h>
using namespace std;
typedef int Int;
#define int long long
#define INF 0x3f3f3f3f
#define maxn 200000
const int mod=1e9+7;
int a[maxn];
vector<int>g[maxn];
set<int>s[maxn];
int ans=0;
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
map<int,int>mp[maxn];
void dfs(int u,int p){
    for(auto v:g[u]){
        if(v==p) continue;
        for(auto vv:s[u]){ //通过父节点进行转移
            int t=gcd(vv,a[v]);
            (ans+=t%mod*mp[u][vv]%mod)%=mod; //贡献为取值乘以出现的次数。
            mp[v][t]+=mp[u][vv]; //更新t值出现的次数
            s[v].insert(t);
        }
        s[v].insert(a[v]);(ans+=a[v]%mod)%=mod; //最后把自己放入
        mp[v][a[v]]++;
        dfs(v,u);
    }
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;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].push_back(v);
        g[v].push_back(u);
    }
    s[1].insert(a[1]);ans=a[1]%mod;mp[1][a[1]]=1;
    dfs(1,-1);
    cout<<ans<<endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/--Simon/p/11598661.html