题目链接
思路:一条链上的gcd最多只要log个,且一定是逐级递减的,根据这个性质我们每递归一个节点,保存一下它的所有可能的gcd来计算每个节点的贡献,同时还能降低复杂度,因为gcd不同的个数最多只有log个,所有不会tle。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+1;
const int mod=1e9+7;
vector<int>g[maxn];
map<ll,ll>p[maxn];
ll num[maxn],ans;
void dfs(int u,int fa)
{
for(auto it:p[fa])
{
ll temp=__gcd(num[u],it.first);
p[u][temp]+=it.second;
ans=(ans+temp%mod*it.second%mod)%mod;
}
p[u][num[u]]++;
ans=(ans+num[u])%mod;
for(int to:g[u])
{
if(to==fa) continue;
dfs(to,u);
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%lld",&num[i]);
for(int i=1,u,v;i<n;++i){
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,0);
printf("%lld\n",ans);
}