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

Input
3
2 3 4
1 2
2 3
Output
1
Input
3
2 3 4
1 3
2 3
Output
2
Input
3
1 1 1
1 2
2 3
Output
0

题意:让你求最长的路径长度,满足路上gcd不为1;

思路:分治的做法比较暴力,但是时限比较长,有板子就直接上了。 由于gcd具有收敛性,路径上的gcd不会太多,而且越远回越接近1,我们记录每一个gcd的最深的位置即可。  (我用的以前的板子,所以用了map,此题的数据量可以不用map

还有一个思路,我们枚举素因子,然后把含有这个素因子的点标记出来,求他们的最远距离,更新答案。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=;
const int inf=0x7FFFFFFF;
int Laxt[maxn],Next[maxn<<],To[maxn<<],cnt,N,sn;
int a[maxn],sz[maxn],son[maxn],vis[maxn],root,res;
int dep[maxn];
ll ans[maxn];
map<int,int>mp,tp;
map<int,int>::iterator it1,it2;
inline void read(int &x) {
x=; char c=getchar();
while(c>''||c<'') c=getchar();
while(c<=''&&c>='') x=(x<<)+(x<<)+c-'',c=getchar();
}
void add(int u,int v){
Next[++cnt]=Laxt[u];
Laxt[u]=cnt; To[cnt]=v;
}
void getroot(int u,int fa) //找重心
{
sz[u]=; son[u]=;
for(int i=Laxt[u];i;i=Next[i]){
if(To[i]!=fa&&!vis[To[i]]){
getroot(To[i],u);
sz[u]+=sz[To[i]];
son[u]=max(son[u],sz[To[i]]);
}
}
son[u]=max(son[u],sn-son[u]);
if(root==||son[root]>son[u]) root=u;
}
void getans(int u,int fa,int num) //对于当前链产生的新GCD
{
dep[u]=dep[fa]+; tp[num]=max(tp[num],dep[u]);
for(int i=Laxt[u];i;i=Next[i]){
if(!vis[To[i]]&&To[i]!=fa){
getans(To[i],u,__gcd(num,a[To[i]]));
}
}
}
void solve(int u) //解决以u为根的子问题
{
mp.clear(); mp[a[u]]=; ans[a[u]]++; dep[u]=;
for(int i=Laxt[u];i;i=Next[i])
if(!vis[To[i]]) {
tp.clear(); getans(To[i],u,__gcd(a[u],a[To[i]]));
for(it1=mp.begin();it1!=mp.end();it1++)
for(it2=tp.begin();it2!=tp.end();it2++){
int g=__gcd((*it1).first,(*it2).first);
if(g>) res=max(res,(*it1).second+(*it2).second-);
}
for(it2=tp.begin();it2!=tp.end();it2++)
mp[(*it2).first]=max((*it2).second,mp[(*it2).first]);
}
}
void dfs(int u) //分治
{
vis[u]=; solve(u);
for(int i=Laxt[u];i;i=Next[i]){
if(vis[To[i]]) continue;
root=; sn=sz[To[i]];
getroot(To[i],); dfs(root);
}
}
int main()
{
read(N); int u,v,Max=;
for(int i=;i<=N;i++) read(a[i]),Max=max(Max,a[i]);
for(int i=;i<N;i++) {
read(u);read(v);
add(u,v); add(v,u);
}
if(Max>) res=;
root=; sn=N; getroot(,); dfs(root);
printf("%d\n",res);
return ;
}

CodeForces - 1101D:GCD Counting (树分治)的更多相关文章

  1. CF EDU 1101D GCD Counting 树形DP + 质因子分解

    CF EDU 1101D GCD Counting 题意 有一颗树,每个节点有一个值,问树上最长链的长度,要求链上的每个节点的GCD值大于1. 思路 由于每个数的质因子很少,题目的数据200000&l ...

  2. Sereja and Brackets CodeForces - 380C (线段树+分治思路)

    Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...

  3. Ultimate Weirdness of an Array CodeForces - 671C (gcd,线段树)

    大意: 定义一个数列的特征值为两个数gcd的最大值, $f(l,r)$表示数列删除区间$[l,r]$的元素后剩余元素的特征值, 求$\sum_{i=1}^n\sum_{j=i}^n{f(i,j)}$ ...

  4. CF1101D GCD Counting 点分治+质因数分解

    题意:求最长的树上路径点值的 $gcd$ 不为 $1$ 的长度. 由于只要求 $gcd$ 不为一,所以只要 $gcd$ 是一个大于等于 $2$ 的质数的倍数就可以了. 而我们发现 $2\times 1 ...

  5. CodeForces - 990G GCD Counting

    Discription You are given a tree consisting of nn vertices. A number is written on each vertex; the ...

  6. CF990G GCD Counting 点分治+容斥+暴力

    只想出来 $O(nlogn\times 160)$ 的复杂度,没想到还能过~ Code: #include <cstdio> #include <vector> #includ ...

  7. Codeforces 437D The Child and Zoo - 树分治 - 贪心 - 并查集 - 最大生成树

    Of course our child likes walking in a zoo. The zoo has n areas, that are numbered from 1 to n. The ...

  8. Educational Codeforces Round 45 (Rated for Div. 2) G - GCD Counting

    G - GCD Counting 思路:我猜测了一下gcd的个数不会很多,然后我就用dfs回溯的时候用map暴力合并就好啦. 终判被卡了MLE.....  需要每次清空一下子树的map... #inc ...

  9. CF1101D GCD Counting

    题目地址:CF1101D GCD Counting zz的我比赛时以为是树剖或者点分治然后果断放弃了 这道题不能顺着做,而应该从答案入手反着想 由于一个数的质因子实在太少了,因此首先找到每个点的点权的 ...

  10. 【BZOJ-1468】Tree 树分治

    1468: Tree Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 534[Submit][Status][Discuss] ...

随机推荐

  1. MP3文件结构解析(超详细)

    转自:http://blog.csdn.net/u010650845/article/details/53520426 MP3文件结构解析(超详细) 1. MP3文件结构解析 1.1. 概述 1.1. ...

  2. GsonFormat根据返回值json快速构建Model

    Json是一个插件,我们只需要在Android studio中进行安装一下,即可使用. 根据平时的操作,根据浏览器中返回中的数据一行一行敲,其实这样非常麻烦. 有一个简单的方法,可以瞬间生成一个实体类 ...

  3. swiper添加了自动滚动效果,然后用手指划过页面,发现自动滚动效果不生效了

    我给swiper添加了自动滚动效果,然后用手指划过页面,发现自动滚动效果不生效了,哪里出了问题呢? 添加参数 autoplayDisableOnInteraction : false,

  4. 【1】windows下IOS开发基础环境搭建

    一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包:       ...

  5. body中的onload()函数和jQuery中的document.ready()有什么区别?

    1.我们可以在页面中使用多个document.ready(),但只能使用一次onload(). 2.document.ready()函数在页面DOM元素加载完以后就会被调用,而onload()函数则要 ...

  6. nginx入门示例(二)

    nginx使用域名访问 (Tip)      nginx目录解析 conf/nginx.conf   #主要的配置文件目录 html      #nginx的默认发布目录,部署完后 网站会在这个目录 ...

  7. [Leetcode 881]船救人 Boats to Save People 贪心

    [题目] The i-th person has weight people[i], and each boat can carry a maximum weight of limit. Each b ...

  8. 二、求水仙花数,打印出100-999之间所有的"水仙花数"

    所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身. 例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方 public c ...

  9. 查看电脑安装的JDK版本

    1.输入java -d32 -version,若出现如下界面则是32位 2.java -d64 -version,因为是32位的,所以结果如下

  10. ubuntu 实用命令收集

    dig 查看域名解析 最下面server为DNS解析地址 dig google.com sudo -s 转为root方式 curl ip.gs 获取本机外网的ip地理地址 开启ipv4转发功能 /et ...