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. 近期对于windows服务的理解

    1.APP.config的作用   在开发环境下时,根目录下的APP.config里面会填写一些参数之类的.当生成之后,这些参数将会被自动生成在*.exe文件目录中.如图: 其中,.exe文件为Win ...

  2. poj3683 2-sat Priest John's Busiest Day

    Description John is the only priest in his town. September 1st is the John's busiest day in a year b ...

  3. POJ 3179 Corral the Cows

    Corral the Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1352   Accepted: 565 De ...

  4. bzoj 2566 calc 拉格朗日插值

    calc Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 377  Solved: 226[Submit][Status][Discuss] Descr ...

  5. expect 实现本地到远程的scp

    expect文件demo 令文件名为test.exp #!/usr/bin/expect -f set timeout -1 set pwd " set src_file [lindex $ ...

  6. BestCoder Round #39 解题报告

    现场只做出前三题w 不过不管怎样这既是第一次认真打BC 又是第一次体验用在线编译器调代码 订正最后一题花了今天一整个下午(呜呜 收获还是比较大的^_^ Delete wld有n个数(a1,a2,... ...

  7. NOIP2016提高组D1T2 天天爱跑步

    n<=300000个点的树,每个点有个人于第Ti秒观测,有m<=300000个人于时间0开始从Sj跑到Tj,速度1个点每秒,输出每个点上的人观察到的跑步的人的数量. 前25分:直接模拟每条 ...

  8. bzoj 1025 DP

    这道题根据群论的基础知识,我们可以转化成将n拆分成若干数,求这些数 的lcm的方案数 先筛下素数表prime 那么我们可以用DP来解决这个问题,用W[I,J]代表I这个数,拆成若干个数, 其中质因数最 ...

  9. Django-urls路由分发

      例如:127.0.0.0:8000/blog/lucaq.html,当有多个应用时,需要在blog应用下进行路由,我们在blog应用下做一个urls路由分发,就需要include模块实现.   导 ...

  10. Linux内核官方文档atomic_ops.txt【摘自Linux 内核文档】

    摘自Linux内核文档 Documentation/atomic_ops.txt,不是本人原创 Semantics and Behavior of Atomic and Bitmask Operati ...