Discription

You are given a tree consisting of nn vertices. A number is written on each vertex; the number on vertex ii is equal to aiai.

Let's denote the function g(x,y)g(x,y) as the greatest common divisor of the numbers written on the vertices belonging to the simple path from vertex xx to vertex yy(including these two vertices).

For every integer from 11 to 2⋅1052⋅105 you have to count the number of pairs (x,y)(x,y) (1≤x≤y≤n)(1≤x≤y≤n) such that g(x,y)g(x,y) is equal to this number.

Input

The first line contains one integer nn — the number of vertices (1≤n≤2⋅105)(1≤n≤2⋅105).

The second line contains nn integers a1a1, a2a2, ..., anan (1≤ai≤2⋅105)(1≤ai≤2⋅105) — the numbers written on vertices.

Then n−1n−1 lines follow, each containing two integers xx and yy (1≤x,y≤n,x≠y)(1≤x,y≤n,x≠y)denoting an edge connecting vertex xx with vertex yy. It is guaranteed that these edges form a tree.

Output

For every integer ii from 11 to 2⋅1052⋅105 do the following: if there is no pair (x,y)(x,y) such that x≤yx≤y and g(x,y)=ig(x,y)=i, don't output anything. Otherwise output two integers: iiand the number of aforementioned pairs. You have to consider the values of ii in ascending order.

See the examples for better understanding.

Examples

Input
3
1 2 3
1 2
2 3
Output
1 4
2 1
3 1
Input
6
1 2 4 8 16 32
1 6
6 3
3 4
4 2
6 5
Output
1 6
2 5
4 6
8 1
16 2
32 1
Input
4
9 16 144 6
1 3
2 3
4 3
Output
1 1
2 1
3 1
6 2
9 2
16 2
144 1 震惊,玄学做法竟然跑过了点分治。。。。
很显然,我们可以先求出g是i倍数的点对数ans[i],然后再反演出答案。
求g是i倍数的点对数的时候就调和级数枚举一下倍数,然后并查集一下就ojbk了。。。 虽然这种做法对于随机数据来说非常的强大,但是一遇到精心构造的数据就gg了,这就是窝一开始TLE的原因。。。
比如n个点的点权都是 <=2e5 的约数最多的数,那么上述做法的总运算次数大致是 O((n+m) * div * 反阿科玛函数),就凉凉了。。。 后来我加了一个比较强的剪枝就过了:
当所有点权都是i的倍数的时候,那就不做并查集,而是直接用 C(n+1,2) 减去 >i且是i倍数的J的ans... 感谢出题人不卡之恩2333
#include<bits/stdc++.h>
#define ll long long
using namespace std;
#define pb push_back
const int maxn=200005; inline int read(){
int x=0; char ch=getchar();
for(;!isdigit(ch);ch=getchar());
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x;
} void W(ll x){ if(x>=10) W(x/10); putchar(x%10+'0');} int n,m,hd[maxn],ne[maxn*2],to[maxn*2],num,cnt[maxn];
int siz[maxn],dfn[maxn],dc,p[maxn],a[maxn];
vector<int> pt[maxn];
ll ans[maxn]; inline void add(int x,int y){ to[++num]=y,ne[num]=hd[x],hd[x]=num;} int getf(int x){ return p[x]==x?x:(p[x]=getf(p[x]));} inline void solve(){
for(int i=2e5,O;i;i--){
dc++,O=0; for(int j=i;j<=2e5;j+=i) O+=cnt[j],ans[i]-=ans[j]; if(O==n){
ans[i]+=n*(ll)(n+1)>>1;
continue;
} for(int j=i;j<=2e5;j+=i){ for(int l=pt[j].size()-1,now;l>=0;l--){
now=pt[j][l]; if(dfn[now]!=dc) dfn[now]=dc,p[now]=now,siz[now]=1,ans[i]++; for(int k=hd[now],fa,fb;k;k=ne[k]) if(dfn[to[k]]==dc){
fa=getf(now),fb=getf(to[k]); if(fa!=fb){
p[fb]=fa,ans[i]+=siz[fa]*(ll)siz[fb];
siz[fa]+=siz[fb];
}
}
}
}
}
} int main(){
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout); n=read();
for(int i=1;i<=n;i++) a[i]=read(),pt[a[i]].pb(i),cnt[a[i]]++; int uu,vv;
for(int i=1;i<n;i++)
uu=read(),vv=read(),add(uu,vv),add(vv,uu); solve(); for(int i=1;i<=2e5;i++) if(ans[i]) W(i),putchar(' '),W(ans[i]),puts("");
return 0;
}

  

 

CodeForces - 990G GCD Counting的更多相关文章

  1. cf 990G - GCD Counting

    题意 #include<bits/stdc++.h> #define t 200000 #define MAXN 200100 using namespace std; int n; in ...

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

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

  3. CF1101D GCD Counting

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

  4. Codeforces 954H Path Counting 【DP计数】*

    Codeforces 954H Path Counting LINK 题目大意:给你一棵n层的树,第i层的每个节点有a[i]个儿子节点,然后问你树上的简单路径中长度在1~n*2-2之间的每个有多少条 ...

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

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

  6. GCD Counting Codeforces - 990G

    https://www.luogu.org/problemnew/show/CF990G 耶,又一道好题被我浪费掉了,不会做.. 显然可以反演,在这之前只需对于每个i,统计出有多少(x,y),满足x到 ...

  7. CodeForces - 1101D:GCD Counting (树分治)

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

  8. codeforces 582A. GCD Table 解题报告

    题目链接:http://codeforces.com/problemset/problem/582/A 网上很多题解,就不说了,直接贴代码= = 官方题解: http://codeforces.com ...

  9. D. GCD Counting(树上dp)

    题目链接:http://codeforces.com/contest/1101/problem/D 题目大意:给你n个点,每个点都有权值,然后给你边的关系,问你树上的最大距离.(这里的最大距离指的是这 ...

随机推荐

  1. SpringMVC学习 -- 使用 @RequestMapping 映射请求

    在控制器的类定义及方法出定义出都可以标注 @RequestMapping: 类定义处:提供初步的请求映射信息.相对于 Web 应用的根目录. 方法定义出:提供进一步的细分映射信息.相对于类定义处的 U ...

  2. linux网络编程系列-TCP/IP模型

    ### OSI:open system interconnection ### 开放系统互联网模型是由ISO国际标准化组织定义的网络分层模型,共七层 1. 物理层:物理定义了所有电子及物理设备的规范, ...

  3. 教主泡嫦娥(RQNOJ 595)

    题目描述 [问题背景] 2012年12月21日下午3点14分35秒,全世界各国的总统以及领导人都已经汇聚在中国的方舟上. 但也有很多百姓平民想搭乘方舟,毕竟他们不想就这么离开世界,所以他们决定要么登上 ...

  4. 线段树+矩阵快速幂 Codeforces Round #373 (Div. 2) E

    http://codeforces.com/contest/719/problem/E 题目大意:给你一串数组a,a[i]表示第i个斐波那契数列,有如下操作 ①对[l,r]区间+一个val ②求出[l ...

  5. 【FJWC2017】交错和查询 [线段树]

    交错和查询 Time Limit: 10 Sec  Memory Limit: 256 MB Description 无限循环数字串S由长度为n的循环节s构成.设s为12345(n=5),则数字串S为 ...

  6. codeforces 854 problem E

    E. Boredom Ilya is sitting in a waiting area of Metropolis airport and is bored of looking at time t ...

  7. 【NOI2014】起床困难综合症 位运算+贪心

    这道题先求出0和-1经过处理后的答案 具体看代码吧 #include<cstdio> #include<cstring> #include<algorithm> u ...

  8. hdu 1509 Windows Message Queue (优先队列)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1509 题目大意:每一次输入都有序号和优先级,优先级小的先输出,优先级相同的话则序号小的先输出!第一次用 ...

  9. CVE-2016-6662 mysql RCE测试

    参考:http://bobao.360.cn/learning/detail/3027.html ,我尝试第一种方法 1.先修改mysql_hookandroot_lib.c里面的反弹地址和端口: # ...

  10. python面向对象——类和对象

    一.三大编程范式 编程范式即编程的方法论,标识一种编程风格 三大编程范式: 1.面向过程编程(流水线式) 优点:极大的降低了程序的复杂度 缺点:应用场景固定住了,可扩展性差 2.函数式编程 特点: a ...