题面

原题链接(CF1627D)

You have an array \(a_1,a_2,…,a_n\) consisting of \(n\) distinct integers. You are allowed to perform the following operation on it:

Choose two elements from the array \(a_i\) and \(a_j\) \((i≠j)\) such that \(gcd(a_i,a_j)\) is not present in the array, and add \(gcd(a_i,a_j)\) to the end of the array. Here \(gcd(x,y)\) denotes greatest common divisor (GCD) of integers \(x\) and \(y\).

Note that the array changes after each operation, and the subsequent operations are performed on the new array.

What is the maximum number of times you can perform the operation on the array?

Input

The first line consists of a single integer \(n\) \((2≤n≤10^6)\).

The second line consists of \(n\) integers \(a_1,a_2,…,a_n (1≤a_i≤10^6)\). All ai are distinct.

Output

Output a single line containing one integer — the maximum number of times the operation can be performed on the given array.

Examples

input

5
4 20 1 25 30

output

3

input

3
6 10 15

output

4

Note

In the first example, one of the ways to perform maximum number of operations on the array is:

Pick \(i=1,j=5\) and add \(gcd(a_1,a_5)=gcd(4,30)=2\) to the array.

Pick \(i=2,j=4\) and add \(gcd(a_2,a_4)=gcd(20,25)=5\) to the array.

Pick \(i=2,j=5\) and add \(gcd(a_2,a_5)=gcd(20,30)=10\) to the array.

It can be proved that there is no way to perform more than 3 operations on the original array.

In the second example one can add 3, then 1, then 5, and 2.

大意

给出一个整数的不可重集合,可以对其重复执行以下操作:对于集合内的任意两个数,计算它们的最大公约数(GCD),如果这个GCD不存在于原集合中,就把它加入这个集合。新加入的数也可以在之后的操作中参与计算。重复此操作,求最多能进行的操作次数。

题解

题面的数据达到了1e6,很显然不能枚举每一对数来检查。但是,集合内的元素大小也在1e6范围内,因此可以开一个大小1e6的数组记录这个数有没有出现过。同时GCD还有一个很有用的性质:两个数的GCD不大于两个数的最小值,也就是\(gcd(a_i,a_j) \leq \min (a_i,a_j)\)。所以,如果一个数能够被加入这个集合,它一定比原集合的最大元素还要小。所以我们考虑对答案进行枚举,从1到这个最大值的所有整数全部判断一遍。

怎么判断这个数能否被加入集合呢?首先,如果已经存在于集合中的数肯定不能被加入,因此可以跳过。然后,对于不在集合中的数\(i\),要想让它被加入集合中,必须存在两个数使其最大公约数为\(i\)。也就是说,集合中存在两个数\(a_p=pi,a_q=qi\),其中\(p,q\)互质。由此,我们可以考虑对每一个没有出现的数\(i\),检查所有的\(2i,3i,\dots ,ki \leq \max(a)\)是否出现在集合中。但是,判断互质是一件非常麻烦的事情。所以联想到GCD的另一个重要性质:三个数的GCD等于其中两个数的GCD和另外一个数的GCD,也就是说\(gcd(a_i,a_j,a_k)=gcd(gcd(a_i,a_j),a_k)\),这个性质对\(n\)个数也成立。假设对所有的\(ki\),有三个数\(k_1i,k_2i,k_3i\)出现在了集合中,其中\(k_n\)两两不互质,但是\(k_1,k_2,k_3\)互质,那么我们可以把\(k_4i=gcd(k_1i,k_2i)\)加入到集合中(如果它已经在集合中那么就不用理睬了),然后计算\(gcd(k_4i,k_3i)=i\),将其加入集合。对于\(n\)个元素也同理。据此,我们可以得出,对于任意一个未出现在集合内的数\(i\),它能加入集合的充要条件是集合内所有\(i\)的倍数的数的GCD等于\(i\)。

枚举每一个可能的\(i\),对每一个\(i\)作判断计算次数为\(\frac{n}{i}\),对此求和(调和级数)得到线性乘以对数的复杂度,求GCD的复杂度大约为对数级别,因此总体复杂度为\(O(n \log ^2 n)\)。

代码如下:

#include <bits/stdc++.h>
#define GRP \
int T; \
cin >> T; \
rep(C, 1, T)
#define FAST \
ios::sync_with_stdio(false); \
cin.tie(0);
using namespace std;
#define rep(i, a, b) for (int i = a; i <= b; ++i)
#define rrep(i, a, b) for (int i = a; i >= b; --i)
#define elif else if
#define mem(arr, val) memset(arr, val, sizeof(arr))
typedef long long ll;
typedef unsigned long long ull; int n;
int a[1000010];
bool vis[1000010];
int maxx, cnt, num;
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
} int main()
{
FAST;
cin >> n;
mem(vis, 0);
cnt = 0;
cin >> a[1];
maxx = a[1];
vis[a[1]] = true;
rep(i, 2, n)
{
cin >> a[i];
maxx = max(maxx, a[i]);
vis[a[i]] = true;
}
rep(i, 1, maxx) //进行枚举
{
if (vis[i])
{
continue;
}
num = 0; //令一个数和0的GCD等于该数本身,可以简化代码
for (int j = i * 2; j <= maxx; j += i) //枚举所有的倍数
{
if (!vis[j])
{
continue;
}
num = gcd(num, j);
}
if (num == i)
{
cnt++;
}
}
cout << cnt << endl;
return 0;
}

最新文章

  1. 6410移植android4.4.2笔记(持续更新)
  2. ES6新特性:Javascript中的Map和WeakMap对象
  3. NSString几个函数
  4. TCP同步传送数据示例以及可能出现问题分析
  5. CentOS 6.x版本升级Mysql
  6. [设计模式] 3 创建者模式 builder
  7. ubuntu下安装selenium2.0 环境
  8. oracle利用merge更新一表的某列数据到另一表中
  9. IT人士的职业规范——凝视
  10. .NET平台和C#语言
  11. python自动化测试应用-第6篇(WEB测试)--Selenium元素篇
  12. 自己定义View Controller转换动画
  13. nodejs 实现文件拷贝
  14. SQL优化一(SQL使用技巧)
  15. httpclient和httpUrlConnect区别
  16. ssm 整合 redis(简单教程)
  17. OpenStack中MySQL高可用配置
  18. TP v5中Url Compat模式
  19. 51nod 1201 整数划分 基础DP
  20. ECharts 定制 label 样式

热门文章

  1. 生成树Toolkit
  2. 抖音网页版高清视频抓取教程selenium
  3. Mybatis配置错误:java.lang.ExceptionInInitializerError
  4. Java并发机制(7)--线程池ThreadPoolExecutor的使用
  5. 解释Spring支持的几种bean的作用域?
  6. LVS 工作图
  7. python实战----Todo清单续写
  8. C#编写程序,计算数组中奇数之和和偶数之和
  9. 【Android Studio】Gradle统一管理版本号引用配置
  10. audio微信自动播放以及自定义样式