[题解}CF1101D

原题

这道题比较水吧,也没啥好说的

首先,两个数如果有 \(\geq1\) 的公因数,则他们一定有公共质因数

然后对每个数质因数分解

之后 \(dfs\) 更新就可以了

设状态为 \(f[u][i]\) , 表示 \(u\) 节点向下,以 \(a[u]\) 的第 \(i\) 个质因数为公因数,向下的深度

先更新 \(ans\)

\[ans=max(ans,f[u][k]+f[v][j]); \]

再更新 \(f[u][k]\)

\[f[u][k]=max(f[u][k],f[v][j]+1); \]

同时为了分解质因数快一点,我们可以先把质数筛出来(懒得打欧拉筛,就用埃氏筛凑合吧,反正数据不大)

代码


#include<bits/stdc++.h>
namespace my_std
{
    using namespace std;
    #define R register
    #define rep(i,a,b) for (R int i=(a);i<=(b);i++)
    #define drep(i,a,b) for (R int i=(a);i>=(b);i--)
    #define go(u) for (R int i=head[(u)];i;i=e[i].nxt)
    #define pf printf
    #define writeln(x) write(x),putchar('\n')
    #define writesp(x) write(x),putchar(' ')
    #define mem(x,v) memset(x,v,sizeof(x))
    typedef long long ll;
    const int INF=0x7fffffff;
    inline int read()
    {
        int sum=0,f=0;
        char c=getchar();
        while (!isdigit(c))
        {
            f|=(c=='-');
            c=getchar();
        }
        while (isdigit(c))
        {
            sum=(sum<<1)+(sum<<3)+(c^48);
            c=getchar();
        }
        return f?-sum:sum;
    }
    void write(int k)
    {
        if (k<0) putchar('-'),k=-k;
        if (k>=10) write(k/10);
        putchar(k%10+'0');
    }
    inline void chkmax(int &x,int y)
    {
    	if (x<y) x=y;
    }
    inline void chkmin(int &x,int y)
    {
    	if (x>y) x=y;
    }
    #define templ template<typename T>
}
using namespace my_std;
const int N=1000010;
int n,ans,cnt,flag,a[N],head[N],f[N][15];
int top,prime[N],isprime[N];
struct edge
{
	int to,nxt;
}e[N<<1];
vector<int>G[N];
inline void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
inline void get_prime(int n)
{
	mem(isprime,1);
	isprime[0]=isprime[1]=0;
	rep(i,2,n) if (isprime[i])
	{
		prime[++top]=i;
		for (int j=i<<1;j<=n;j+=i)
		{
			isprime[j]=0;
		}
	}
}
inline void split(int u)
{
	int x=a[u];
	rep(i,1,top) if (x%prime[i]==0)
	{
		G[u].push_back(prime[i]);
		while (x%prime[i]==0) x/=prime[i];
	}
	if (x!=1) G[u].push_back(x);
}
void dfs(int u,int fa)
{
	if (G[u].size()>=1) rep(i,0,G[u].size()-1) f[u][i]=1;
	go(u)
	{
		int v=e[i].to;
		if (v==fa) continue;
		dfs(v,u);
		if (G[u].size()>=1) rep(k,0,G[u].size()-1) if (G[v].size()>=1) rep(j,0,G[v].size()-1) if (G[u][k]==G[v][j])
		{
			chkmax(ans,f[u][k]+f[v][j]);
			chkmax(f[u][k],f[v][j]+1);
		}
	}
}
int main()
{
	n=read();
	get_prime(sqrt(200000));
	rep(i,1,n) a[i]=read(),flag|=(a[i]>1);
	if (!flag)
	{
		writeln(0);
		return 0;
	}
	rep(i,1,n-1)
	{
		int u=read(),v=read();
		add(u,v),add(v,u);
	}
	ans=1;
	rep(i,1,n) split(i);
	dfs(1,0);
	writeln(ans);
        return 0;
}
posted @ 2020-04-01 15:27  ZSH_ZSH  阅读(286)  评论(5)    收藏  举报