数论因数D. Not Adding

Posted 行码棋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论因数D. Not Adding相关的知识,希望对你有一定的参考价值。

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)

D. Not Quite Lee(裴蜀定理gcdlowbit)

数论-素数筛法小结

简单数论之整除&质因数分解&唯一分解定理

[数论]欧拉函数&素数筛

数论8——欧拉函数