Codeforces Round #766 (Div. 2)
题意
给出含有n个数的序列a。可以对序列a进行以下操作:每次选择任意两个数,若这两个数的gcd不在这个序列中,则将这两个数的gcd加入该序列中。
问:最多可以进行多少次该操作。
2
≤
n
≤
1
0
6
1
≤
a
[
i
]
≤
1
0
6
2 \leq n \leq 10^6 \\ 1\leq a[i] \leq 10^6
2≤n≤1061≤a[i]≤106
思路
数论。
- 由于数列中的数范围较小,可以枚举所有的数。对于任意一个数i,将该数列中是i的倍数的数取出;然后将这些数都除去 i,若得到的这些数的gcd为1,则i 一定在这个数列中。
例如:i = 3, a中是i的倍数的数为:6, 15。除去3后得:2, 5。gcd(2, 5) = 1。所以3在之后得操作中一定会被加入在这个序列中。 - 由于是从小到大枚举的,所以这些中途加入的数,一定不会是后来枚举到的数的倍数。
代码
const int N = 2e5 + 7, M = 1e6 + 10;
int a[M];
int gcd(int a, int b)
{
if (b == 0) return a;
return gcd(b, a % b);
}
int main()
{
IOS;
int n; cin >> n;
for (int x, i = 0; i < n; i++)
{
cin >> x; a[x] = 1;
}
int ans = 0;
for (int i = 1; i < M - 7; i++)
{
int d = 0;
for (int j = i; j < M - 7; j += i)
if (a[j]) d = gcd(d, j / i);
if (d == 1 && !a[i]) ans++;
//注意:需要判断一下这个数是否以及在这个序列中
}
cout << ans << endl;
return 0;
}