Dasha Code Championship - SPb Finals Round C. Kamil and Making a Strea(树上gcd+dfs)

题目链接
在这里插入图片描述
在这里插入图片描述
思路:一条链上的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);
 } 
发布了144 篇原创文章 · 获赞 0 · 访问量 4944

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/104523735