[CodeM初赛A轮]D

来源:互联网 发布:知世故而不世故, 编辑:程序博客网 时间:2024/06/01 07:21

题解

用sqrt(a)/log a的时间分解质因数。
枚举一个质因数x,所有x的倍数节点打标记。
对于每一个被标记的联通块求直径。

#include<cstdio>#include<algorithm>#include<map>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;typedef long long ll;const int maxn=100000+10,maxd=32000+10;map<int,int> id;int h[maxn],go[maxn*2],nxt[maxn*2],a[maxn],b[maxn*11],f[maxn];int h2[maxn*11],g2[maxn*11],n2[maxn*11];int pri[maxd];bool bz[maxd],pd[maxn],vis[maxn];int i,j,k,l,t,n,m,tot,top,num,cnt,ans,mx,now;int read(){    int x=0,f=1;    char ch=getchar();    while (ch<'0'||ch>'9'){        if (ch=='-') f=-1;        ch=getchar();    }    while (ch>='0'&&ch<='9'){        x=x*10+ch-'0';        ch=getchar();    }    return x*f;}void prepare(){    fo(i,2,maxd-10){        if (!bz[i]) pri[++top]=i;        fo(j,1,top){            if ((ll)i*pri[j]>maxd-10) break;            bz[i*pri[j]]=1;            if (i%pri[j]==0) break;        }    }}void add(int x,int y){    go[++tot]=y;    nxt[tot]=h[x];    h[x]=tot;}void add2(int x,int y){    g2[++cnt]=y;    n2[cnt]=h2[x];    h2[x]=cnt;}void dfs(int x,int y,int z){    vis[x]=1;    if (z>now) mx=x,now=z;    int t=h[x];    while (t){        if (go[t]!=y&&pd[go[t]]) dfs(go[t],x,z+1);        t=nxt[t];    }}int main(){    prepare();    n=read();    fo(i,1,n-1){        j=read();k=read();        add(j,k);add(k,j);    }    tot=0;    fo(i,1,n){        a[i]=read();        k=a[i];        fo(j,1,top){            if ((ll)pri[j]*pri[j]>k) break;            if (k%pri[j]==0){                if (id[pri[j]]==0) id[pri[j]]=++tot,b[++num]=pri[j];                add2(id[pri[j]],i);                while (k%pri[j]==0) k/=pri[j];            }        }        if (k>1){            if (id[k]==0) id[k]=++tot,b[++num]=k;            add2(id[k],i);        }    }    fo(i,1,num){        t=h2[id[b[i]]];        while (t){            pd[g2[t]]=1;            t=n2[t];        }        t=h2[id[b[i]]];        while (t){            if (!vis[g2[t]]){                mx=0;now=-1;                dfs(g2[t],0,0);                now=-1;                dfs(mx,0,0);                ans=max(ans,now);            }            t=n2[t];        }        t=h2[id[b[i]]];        while (t){            vis[g2[t]]=0;            t=n2[t];        }        t=h2[id[b[i]]];        while (t){            pd[g2[t]]=0;            t=n2[t];        }    }    printf("%d\n",ans+1);}
原创粉丝点击