• [题解}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('
    ')
        #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;
    }
  • 相关阅读:
    业务领域建模Domain Modeling
    用例建模Use Case Modeling
    分析一套源代码的代码规范和风格并讨论如何改进优化代码
    结合工程实践选题调研分析同类软件产品
    如何提高程序员的键盘使用效率?
    CSS水平布局
    CSS文档流
    CSS盒子模型
    CSS单位
    CSS选择器的权重
  • 原文地址:https://www.cnblogs.com/ZHANG-SHENG-HAO/p/12612879.html
Copyright © 2020-2023  润新知