数论因数D. Not Adding
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论因数D. Not Adding相关的知识,希望对你有一定的参考价值。
- 博客主页: https://blog.csdn.net/qq_50285142
- 👍欢迎点赞👍⭐️收藏⭐️❤️关注❤️留言 📝 如有错误,敬请指正
- 🎈点击领取大量学习资源🎈
D. Not Adding【CF】【因数】
链接 : https://codeforces.com/problemset/problem/1627/D
一个数组,可以进行一个操作,对数组中的两个数 a i , a j a_i,a_j ai,aj做 g c d ( a i , a j ) gcd(a_i,a_j) gcd(ai,aj)操作,结果如果不存在这个数组中,可以加在这个数组中。问最多进行多少次操作。
明确:
- 首先
gcd
的结果一定是小于等于做操作的两个数的,所以数组中数的大小一定小于数组中的最大值 a m a x a_max amax -
a
i
,
a
j
a_i,a_j
ai,aj的最大公因数等于
x
,则 a i , a j a_i,a_j ai,aj都是x
的倍数。所以多个数做gcd结果为y
,那么这些数都是y
的倍数
做法:
cnt
代表数组可以产生的最大长度- 使用
cur[i]
数组记录是i
的倍数且在本数组中出现的所有数的gcd
,只有在本数组出现才会被计算gcd
- 枚举每个数,看它的倍数是否在数组中出现过,如果出现,进行
gcd
操作,最后枚举完i
的所有倍数,cur[i]
的结果就是本数组中所有i
的倍数的数的gcd
值 - 如果该
gcd
值等于i
,那么i
就可以被得到,cnt
加一 - 最后
cnt
-n
即为结果
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
bool in[N];
int cur[N];
int main()
int n;
cin>>n;
for(int i=1;i<=n;i++)
int x;cin>>x;
in[x] ++;
int tot = 0;
for(int i=1;i<N;i++)
for(int j=i;j<N;j+=i)
if(in[j])
cur[i] = __gcd(cur[i],j);
tot += (cur[i] == i);
cout<<tot - n << endl;
return 0;
往期优质文章推荐
领取大量学习资源
以上是关于数论因数D. Not Adding的主要内容,如果未能解决你的问题,请参考以下文章
D. Not Quite Lee(裴蜀定理gcdlowbit)