我是靠谱客的博主 秀丽曲奇,最近开发中收集的这篇文章主要介绍Educational Codeforces Round 58 (Rated for Div. 2) D.GCD Counting,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
D. GCD Counting
time limit per test4.5 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a tree consisting of n vertices. A number is written on each vertex; the number on vertex i is equal to ai.
Let's denote the function g(x,y) as the greatest common divisor of the numbers written on the vertices belonging to the simple path from vertex x to vertex y (including these two vertices). Also let's denote dist(x,y) as the number of vertices on the simple path between vertices x and y, including the endpoints. dist(x,x)=1 for every vertex x.
Your task is calculate the maximum value of dist(x,y) among such pairs of vertices that g(x,y)>1.
Input
The first line contains one integer n — the number of vertices (1≤n≤2⋅105).
The second line contains n integers a1, a2, ..., an (1≤ai≤2⋅105) — the numbers written on vertices.
Then n−1 lines follow, each containing two integers x and y (1≤x,y≤n,x≠y) denoting an edge connecting vertex x with vertex y. It is guaranteed that these edges form a tree.
Output
If there is no pair of vertices x,y such that g(x,y)>1, print 0. Otherwise print the maximum value of dist(x,y) among such pairs.
Examples
inputCopy
3
2 3 4
1 2
2 3
outputCopy
1
inputCopy
3
2 3 4
1 3
2 3
outputCopy
2
inputCopy
3
1 1 1
1 2
2 3
outputCopy
0
题意:
函数g(x,y)表示为:写在属于从顶点x到顶点y(包括这两个顶点)的简单路径的顶点上的数字的最大公约数。
另外,让我们将dist(x,y)表示为顶点x和y之间的简单路径上的顶点数,包括端点。
每个顶点x的dist(x,x)= 1。
任务是计算g(x,y)> 1的顶点对中dist(x,y)的最大值。
如果没有顶点对x,y使得g(x,y)> 1,则打印0.否则在这些对中打印dist(x,y)的最大值。
分析:
将每个gcd分解素因子放入对应vector
相当于对每个素因子建了一棵树
遍历每个素因子的树,寻找直径,更新答案
#include<bits/stdc++.h>
using namespace std;
#define ll __int64
const int maxn=2e5+10;
int n,a[maxn],vis[maxn],vis1[maxn],ans=1,flag=1,md,mp,p[maxn];
struct edge
{
int u,v;
edge(int uu,int vv):u(uu),v(vv){
}
};
vector<edge>e[maxn];
vector<int> v[maxn];
void dfs(int p,int d,int *vis)
{
if(vis[p])return;
vis[p]=1;
if(d>md)md=d,mp=p;
for(int i=0;i<v[p].size();++i)
dfs(v[p][i],d+1,vis);
}
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int main()
{
for(ll i=2;i<maxn;++i)
{
if(!p[i])
{
for(ll j=i*i;j<maxn;j+=i)
p[j]=1;
}
}
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d",a+i),a[i]>1&&(flag=0);//短路判均<=1
}
if(flag)
{
puts("0");
return 0;
}
for(int i=1;i<n;++i)
{
int u,v,k;
scanf("%d%d",&u,&v);
if((k=gcd(a[u],a[v]))>1)
{
for(int j=1;j*j<=k;++j)//j从1开始是为了判k
{
if(k%j==0)
{
if(!p[j]&&j!=1)e[j].push_back(edge(u,v));
if(j*j!=k&&!p[k/j])e[k/j].push_back(edge(u,v));
}
}
}
}
for(int i=2;i<maxn;++i)
{
if(!p[i])
{
vector<int> p;
for(int j=0;j<e[i].size();++j)
{
edge& E=e[i][j];
p.push_back(E.u);
p.push_back(E.v);
v[E.u].push_back(E.v);
v[E.v].push_back(E.u);
}
for(int j=0;j<p.size();++j)
{
vis[p[j]]=vis1[p[j]]=0;
}
for(int j=0;j<p.size();++j)
{
if(!vis[p[j]])
{
md=0;
dfs(p[j],1,vis);
md=0;
dfs(mp,1,vis1);
ans=max(ans,md);
}
}
for(int j=0;j<p.size();++j)
v[p[j]].clear();
}
}
printf("%dn",ans);
return 0;
}
最后
以上就是秀丽曲奇为你收集整理的Educational Codeforces Round 58 (Rated for Div. 2) D.GCD Counting的全部内容,希望文章能够帮你解决Educational Codeforces Round 58 (Rated for Div. 2) D.GCD Counting所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复