zoukankan      html  css  js  c++  java
  • 最大公约数

    https://zybuluo.com/ysner/note/1175822

    题面

    现有(n)个数,询问选出(k)个数的(gcd)的最大值。

    • (30pts) (nleq20)
    • (60pts) 保证输入中所有数小于(5000)
    • (100pts) 保证输入中所有数小于(500000)
    • (kleq n)

    解析

    (nleq20)

    (O(2^n))枚举。

    (nleq5000)

    枚举(gcd)最大值,看是否有(k)个数能将其除尽。

    (nleq5*10^5)

    话说我想了半天为什么不给出(n)的范围,竟然没想到是因要开桶,(n)的范围无意义。。。
    于是我们开个桶(a[i])记录每个数出现多少次。
    然后枚举(gcd)最大值。
    要判断有多少个数能将其除尽,直接枚举(t)(sum a[gcd*t](tin N^*))即可。
    复杂度最坏为$$O(n+frac{n}{2}+frac{n}{3}+...+1)$$
    等价于(O(nlogn))

    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #define ll long long
    #define re register
    #define il inline
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=5e5+100;
    int n,k,a[N],ans=1,mx;
    int main()
    {
      freopen("gcd.in","r",stdin);
      freopen("gcd.out","w",stdout);
      n=gi();k=gi();
      fp(i,1,n)
        {
          re int x=gi();mx=max(mx,x);
          a[x]++;
        }
      fq(i,mx,1)
        {
          re int sum=0;
          for(re int j=1;j*i<=mx;j++) sum+=a[j*i];
          if(sum>=k) {printf("%lld
    ",1ll*k*i);return 0;}
        }
      fclose(stdin);
      fclose(stdout);
      return 0;
    }
    
  • 相关阅读:
    ch_6802 車的放置
    ch_POJ2182 Lost Cows
    ch_4201 楼兰图腾
    luogu_P3368【模板】树状数组 2
    门面
    建造者
    模板方法
    状态
    抽象工厂
    工厂方法
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9155453.html
Copyright © 2011-2022 走看看