zoukankan      html  css  js  c++  java
  • GCD Counting-树形DP

    GCD Counting

    思路: 预处理  每个权值的素因子。问题转化为  以同一个素数作为因子 最长的链,

    树形DP求解,ans 由 此点的 最长子链 + 次长子链 相加得到, 然后再更新最长子链

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 234567
    int pri[maxn+10],n,a[maxn+10];
    int x,y,dp[maxn+10][30],id,ans;
    int head[maxn+10],cnt,sum[maxn];
    vector<int>p[maxn+10];
    bool isprime[maxn+10],flag;
    struct node
    {
        int v,to;
    } edge[maxn*2];
    void add(int u,int v)
    {
        edge[++cnt].v=v;
        edge[cnt].to=head[u];
        head[u]=cnt;
    }
    void prime()
    {
        isprime[0]=isprime[1]=1;
        for(int i=2; i<=sqrt(maxn); i++)
            for(int j=i*i; j<maxn; j+=i)
                isprime[j]=1;
        for(int i=2; i<=maxn; i++)
            if(isprime[i]==0)pri[++id]=i;
    }
    void dfs(int u,int fa)
    {
        for(int i=head[u]; i!=-1; i=edge[i].to)
        {
            int v=edge[i].v;
            if(v==fa)continue;
            dfs(v,u);
            int len1=sum[u];
            int len2=sum[v];
            for(int j=0; j<len1; j++)
                for(int k=0; k<len2; k++)
                    if(p[u][j]==p[v][k])
                    {
                        ans=max(ans,dp[u][j]+dp[v][k]+1);
                        dp[u][j]=max(dp[u][j],dp[v][k]+1);
                    }
        }
    }
    int main()
    {
        prime();
        memset(head,-1,sizeof(head));
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            if(a[i]==1)continue;
            else flag=1;
            for(int j=1; pri[j]<=a[i]&&j<=id; j++)
            {
                if(a[i]==1)break;
                if(a[i]%pri[j]==0)
                {
                    p[i].push_back(pri[j]);
                    sum[i]++;
                }
                while(a[i]%pri[j]==0)
                    a[i]/=pri[j];
                if(isprime[a[i]]==0)
                {
                    p[i].push_back(a[i]);
                    sum[i]++;
                    break;
                }
            }
        }
        for(int i=1; i<n; i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        if(!flag)printf("0
    ");
        else
        {
            dfs(1,0);
            printf("%d
    ",ans+1);
        }
        return 0;
    }
    

      

  • 相关阅读:
    共望明月
    游丽都公园有感
    创业天才尼尔曼迈向成功的十四个原则
    赵娜(帮别人名字作诗)
    小幽默也有大道理:哲理幽默15则
    夜游草堂
    成功就是简单的事情重复做、重复做
    千万别入错行 15条人生建议
    听一堂课值三十九万,把它看完,定会有收获!
    VIEW:X$KCCRSControlfile Record Section directory (8.0 8.1)
  • 原文地址:https://www.cnblogs.com/SDUTNING/p/10270962.html
Copyright © 2011-2022 走看看