[题解}CF1101D

原题

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

首先,两个数如果有 1 的公因数,则他们一定有公共质因数

然后对每个数质因数分解

之后 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 @   ZSH_ZSH  阅读(283)  评论(5编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示