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

    题意:给你\(n\)个数,去掉尽量少的数使得剩下数的\(gcd\)比原来的大,无解输出\(-1\)

    题目意思很简洁,想理出来一个清晰的思路却花了不少时间......首先先计算出总的\(GCD\),然后再把每个数都除去这个\(GCD\),接下来的事情就得仔细考虑一下了。

    \(M=max\left\{a[i]\right\}\),则若枚举\(1-M\)内所有质数(显然枚举质数比合数优)并一一判断在\(1-n\)中整除它们的数字的个数,复杂度为\(O(\frac{nM}{log\,M})\)必须爆炸。当时想到这里就优化不下去了,于是凉凉。实际上有一种看似暴力的方法可以较优地解决这个问题:我们开一个数组\(b[i]\),并在每一个\(b[a[i]]\)的位置上加一,那么当我们枚举质数的时候将其所有倍数上的数组\(b\)的值加在一起就可以更新答案了。运行次数大概是\(\sum \limits_{i为质数且i \le M}\frac{M}{i}\),这东西收敛得比较快,所以复杂度可以接受

    代码如下:

    #include<cstdio>
    #include<iostream>
    #define INF 1000000000
    using namespace std;
    const int N=3e5+10;
    const int M=1.5e7+10;
    int n,a[N],GCD,primes[M],v[M],cnt,num[M],sum,ans=INF,maxn;
    inline int exgcd(int x,int y){int r;while(x&&y){r=x%y;x=y;y=r;}return x;}
    inline void Primes_Table(){
        for(register int i=2;i<=M-10;i++){
            if(!v[i]){v[i]=i;primes[++cnt]=i;}
            for(register int j=1;j<=cnt&&i*primes[j]<=M-10;j++){
                if(v[i]<primes[j])continue;v[i*primes[j]]=primes[j];}
        }
    }
    int main(){
        Primes_Table();scanf("%d",&n);
        for(register int i=1;i<=n;i++)scanf("%d",&a[i]);
        GCD=a[1];for(register int i=2;i<=n;i++)GCD=exgcd(GCD,a[i]);
        for(register int i=1;i<=n;i++)a[i]/=GCD,maxn=max(maxn,a[i]);
        for(register int i=1;i<=n;i++)num[a[i]]++;
        for(register int i=1;i<=cnt;i++){sum=0;
            for(register int j=primes[i];j<=maxn;j+=primes[i])sum+=num[j];
            ans=min(ans,n-sum);}
        printf("%d\n",ans==n? -1:ans);return 0;
    }
    
  • 相关阅读:
    tile38 复制配置
    The Guardian’s Migration from MongoDB to PostgreSQL on Amazon RDS
    tile38 一款开源的geo 数据库
    sqler sql 转rest api 的docker 镜像构建(续)使用源码编译
    sqler sql 转rest api javascript 试用
    sqler sql 转rest api redis 接口使用
    sqler sql 转rest api 的docker image
    sqler sql 转rest api 的工具试用
    apache geode 试用
    benthos v1 的一些新功能
  • 原文地址:https://www.cnblogs.com/ForwardFuture/p/9738837.html
Copyright © 2011-2022 走看看