【loj6159】「美团 CodeM 初赛 Round A」最长树链

来源:互联网 发布:气相色谱图数据怎么看 编辑:程序博客网 时间:2024/06/11 22:05

题目描述
Mr. Walker\text{Mr. Walker}Mr. Walker最近在研究树,尤其是最长树链问题。现在树中的每个点都有一个值,他想在树中找出最长的链,使得这条链上对应点的值的最大公约数不等于111。请求出这条最长的树链的长度。
输入格式
第一行一个整数 nnn,表示点的个数。

接下来n−1n-1n−1行,每行两个整数x,yx,yx,y表示x,yx,yx,y之间有边。

数据保证给出的是一棵树。

接下来一行nnn个整数表示每个点对应的权值 aia_ia
​i
​​
输出格式
输出一个整数,表示这条树链的长度。
样例
样例输入

4
1 2
1 3
2 4
6 4 5 2
样例输出

3
数据范围与提示
1≤n≤1000001 \leq n \leq 1000001≤n≤100000

1≤ai≤1091 \leq a_i \leq 10^91≤a
​i
​​ ≤10
​9
​​

题解
枚举所有包含的质因子,把含有这个因子的点取出来,求直径即可。

代码

#include<bits/stdc++.h>#define ll long long#define inf 1000000000using namespace std;inline 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;}map<int,int>mp;int tot,ans,N;vector<int>l[100005],g[100005];int n,dis[100005];bool flag[100005],vis[100005],mark[100005];int bfs(int u){    queue<int>q;int ans=0;    q.push(u);vis[u]=1;dis[u]=1;    while (!q.empty())    {        int now=q.front();q.pop();        for (int i=0;i<l[now].size();i++)        {            if (!mark[l[now][i]]) continue;            if (vis[l[now][i]]) continue;            dis[l[now][i]]=dis[now]+1;            if (dis[l[now][i]]>dis[ans]) ans=l[now][i];            q.push(l[now][i]);vis[l[now][i]]=1;        }    }    q.push(ans);flag[ans]=1;dis[ans]=1;    while (!q.empty())    {        int now=q.front();q.pop();        for (int i=0;i<l[now].size();i++)        {            if (!mark[l[now][i]]) continue;            if (flag[l[now][i]]) continue;            dis[l[now][i]]=dis[now]+1;            if (dis[l[now][i]]>dis[ans]) ans=l[now][i];            q.push(l[now][i]);flag[now]=1;        }    }    return dis[ans];}int main(){    n=read();    for (int i=1;i<n;i++)    {        int x=read(),y=read();        l[x].push_back(y);        l[y].push_back(x);    }    for (int i=1;i<=n;i++)    {        int x=read();        for (int j=2;j*j<=x;j++)if (x%j==0)        {            g[mp[j]?mp[j]:(mp[j]=++N)].push_back(i);            while (x%j==0) x/=j;            if (x==1) break;        }        if (x!=1) g[mp[x]?mp[x]:(mp[x]=++N)].push_back(i);    }    for (int i=1;i<=N;i++)    {        for (int j=0;j<g[i].size();j++)        {            mark[g[i][j]]=1;            vis[g[i][j]]=0;            flag[g[i][j]]=0;        }        for (int j=0;j<g[i].size();j++)if (!vis[g[i][j]]) ans=max(ans,bfs(g[i][j]));        for (int j=0;j<g[i].size();j++)        {            mark[g[i][j]]=0;            vis[g[i][j]]=1;            flag[g[i][j]]=1;        }    }    cout<<ans;    return 0;}
阅读全文
0 0