zoukankan      html  css  js  c++  java
  • [CF1034A] Enlarge GCD

    Description

    给你 (n) 个数,去掉尽量少的数使得剩下数的最大公约数比原来的大。无解输出 (-1)

    Solution

    首先将所有数除以最大公约数

    (M=max a_i),维护一个桶 (b[]),对每个 (i),在 (b[a[i]])(+1)

    枚举 ([1,M]) 中的所有质数 (p),考虑让最大公约数乘以 (p),代价就是我们需要删去所有的 (a_i) 满足 (p|a_i),于是我们枚举所有 (p) 的整数倍 (q),统计所有 (b[q]) 的和,就是 (p) 的答案

    最后对所有 (p) 的答案取最小值即可

    复杂度是 (sum_{p leq M} M/i),由于收敛较快,可以接受

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 16000005;
    int prime[MAXN+1];
    
    void presolve() {
        memset(prime,0,sizeof prime);
        for(int i=2;i<=MAXN;i++) {
            if(!prime[i]) prime[++prime[0]]=i;
            for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++) {
                prime[prime[j]*i]=1;
                if(i%prime[j]==0) break;
            }
        }
    }
    
    const int N = 1000005;
    int n,a[N],b[MAXN];
    
    signed main() {
        ios::sync_with_stdio(false);
        presolve();
        cin>>n;
        int g=0;
        for(int i=1;i<=n;i++) cin>>a[i], g=__gcd(g,a[i]);
        for(int i=1;i<=n;i++) a[i]/=g;
        for(int i=1;i<=n;i++) b[a[i]]++;
        int M = *max_element(a+1,a+n+1);
        int ans = 2e9;
        for(int i=1;prime[i]<=M;i++) {
            int p=prime[i];
            int sum=0;
            for(register int q=p;q<=M;q+=p) {
                sum+=b[q];
            }
            ans=min(ans,n-sum);
        }
        cout<<(ans>1e9?-1:ans)<<endl;
    }
    
  • 相关阅读:
    找工作就上智联,效果真快,然而让我去的公司都是泡我呢
    只能面深度学习岗和算法岗,其他都不会
    2维矩阵前缀和技巧题目
    计算机基础背诵
    集合函数AVG,SUM,MAX,MIN
    集合函数COUNT
    修改删除数据记录
    多表查询
    查询数据表中的记录
    SQL基本语句(3) LOAD DATA INFILE
  • 原文地址:https://www.cnblogs.com/mollnn/p/12782127.html
Copyright © 2011-2022 走看看