cf842C 树形dp+gcd函数

树形dp用一下就好了

/*
dp[i]表示不删节点的gcd值
每个结点开个vector用来存储删一个点之后的最大值 
然后排序 去重
*/
#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define maxn 200005
struct Edeg{int to,nxt;}edge[maxn<<1];
int n,a[maxn],head[maxn],tot,dp[maxn];
vector<int>vec[maxn];
void init(){
    memset(head,-1,sizeof head);
    tot=0;
}
void addedge(int u,int v){
    edge[tot].to=v;edge[tot].nxt=head[u];head[u]=tot++;
}
void dfs(int u,int pre){
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        if(v==pre)continue;
        dp[v]=__gcd(a[v],dp[u]);//不删点的情况
        vec[v].push_back(dp[u]);//删去v结点
        for(int j=0;j<vec[u].size();j++)//删v以上的点 
            vec[v].push_back(__gcd(a[v],vec[u][j])); 
        sort(vec[v].begin(),vec[v].end());//排序去重 
        vec[v].erase(unique(vec[v].begin(),vec[v].end()),vec[v].end()); 
        dfs(v,u);
    }
}
int main(){
    init();
    int u,v;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<n;i++){
        cin>>u>>v;
        addedge(u,v);
        addedge(v,u);
    }
    dp[1]=a[1];vec[1].push_back(0);
    dfs(1,0);
    for(int i=1;i<=n;i++)
        printf("%d ",max(dp[i],vec[i].back()));
} 

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/10355090.html
今日推荐