codeforce842c Ilya And The Tree

本文介绍了一种利用树形DP算法解决求解树上每个节点到根节点路径中GCD最大值的问题,通过将节点到根节点路径上的数值进行特定变换,实现了高效的求解。

题意:一颗树(n<2e5),每个节点有点权(x<2e5),对于每一个点权,你可以变它或者它祖先的其中一个为0,求每一个点到根节点的gcd的最大值

题解:对于每一个点,可以把每一个存它到根节点的每一个数变为0的gcd,可以知道越往下面走,gcd的可能值就越少

#include <bits/stdc++.h>
#define ll long long
#define maxn 200100
using namespace std;
int a[maxn], g[maxn];
vector<int >G[maxn];
set<int >s[maxn];
int dfs(int x,int fax){
    g[x] = __gcd(a[x], g[fax]);
    s[x].insert(g[fax]);
    for(auto i:s[fax]){
        s[x].insert(__gcd(a[x], i));
    }
    for(int i=0;i<G[x].size();i++){
        int u = G[x][i];
        if(u == fax) continue;
        dfs(u, x);
    }
}
int main(){
    int n, aa, b;
    scanf("%d", &n);
    for(int i=1;i<=n;i++) scanf("%d", &a[i]);
    for(int i=0;i<n-1;i++){
        scanf("%d%d", &aa, &b);
        G[aa].push_back(b);
        G[b].push_back(aa);
    }
    s[0].insert(0);
    dfs(1,0);
    for(int i=1;i<=n;i++)
        cout<<*s[i].rbegin()<<" ";
    cout<<endl;
    return 0;
}

 

转载于:https://www.cnblogs.com/Noevon/p/7460427.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值