D. Not Adding

传送门:CF

正文:

这道题是一道数论题,有两种解法,都挺有趣的。

解法一:

#include
#define maxn 1000005
using namespace std;
int a[maxn];
bool vis[maxn];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n,ans=0; cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],vis[a[i]]=1;
	for(int i=1;i<=1e6;i++)
	{
		if(vis[i]) continue;
		int p=-1;
		for(int j=2*i;j<=1e6;j+=i)
		{
			if(!vis[j]) continue;
			if(p==-1) p=j/i;
			else
			{
				p=__gcd(p,j/i);
				if(p==1) {ans++,vis[j]=1; break;}
			}
		}
	}
	cout<

这里用了一个性质:若干个数只要有两个数是互质的,则gcd(a_{1},a_{2},a_{3},...,a_{n})=1

我们要判断 i 可以不可以通过更大的数得到,就要看存不存在两个数a,b,满足gcd(a/i,b/i)=1

解法二:(代码取自jiangly)

#include 

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int n;
    std::cin >> n;
    
    int m = 0;
    std::vector a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
        m = std::max(m, a[i]);
    }
    
    std::vector f(m + 1);
    for (auto x : a) {
        f[x]++;
    }
    for (int i = 1; i <= m; i++) {
        for (int j = 2 * i; j <= m; j += i) {
            f[i] += f[j];
        }
    }
    
    int ans = 0;
    for (int i = 1; i <= m; i++) {
        bool nice = f[i] > 0;
        for (int j = 2 * i; j <= m; j += i) {
            if (f[i] == f[j]) {
                nice = false;
            }
        }
        ans += nice;
    }
    
    std::cout << ans - n << "\n";
    
    return 0;
}

你可能感兴趣的:(cf,leetcode,算法,职场和发展)