educational codeforces round 58 (div2) D. GCD Counting

这道题每个节点都由子节点的不同状态转移过来,只要子节点可以整除这个节点的的某个质因子,就可以转移。为了遍历找到本节点的质因子对应于这个节点子节点的哪些状态,需要开个map<pair<int,int> ,int>来存储

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
vector<int> G[200001];
vector<int> vec[200001];
int dp[200001][10];
int a[200001];
int ans;
map<P,int> mp;
void dfs(int rt,int fa)
{
    int max1[10],max2[10];
    memset(max1,0,sizeof(max1));
    memset(max2,0,sizeof(max2));
    for(int i=0;i<vec[rt].size();i++)
    {
        int to=vec[rt][i];
        if(to==fa)
          continue;
        dfs(to,rt);
        for(int j=0;j<G[rt].size();j++)
        {
            int num=G[rt][j];
            if(a[to]%num==0)
            {
                int pos=mp[P(num,to)];
                int tmp=dp[to][pos];
                if(tmp>max1[j])
                {
                    max2[j]=max1[j];
                    max1[j]=tmp;
                }
                else if(tmp>max2[j])
                {
                    max2[j]=tmp;
                }
            }
        }
    }
    for(int i=0;i<G[rt].size();i++)
    {
        dp[rt][i]=1+max1[i];
        ans=max(ans,max1[i]+max2[i]+1);
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n;i++)
    {
        int k=a[i];
        for(int j=2;j*j<=k;j++)
        {
            if(k%j==0)
            {
                G[i].push_back(j);
                mp[P(j,i)]=G[i].size()-1;
                while(k%j==0) k/=j;
            }
        }
        if(k>1)
        {
           G[i].push_back(k);
           mp[P(k,i)]=G[i].size()-1;
        }
    }
    for(int i=1;i<=n-1;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        vec[x].push_back(y);
        vec[y].push_back(x);
    }
    dfs(1,-1);
    printf("%d\n",ans);
}

猜你喜欢

转载自www.cnblogs.com/lishengkangshidatiancai/p/10262357.html
今日推荐