• 51nod 1616 最小集合(枚举倍数)


    分析:也就是取任意多个数,它们的最大公约数都在这个集合里。考虑到ai比较小,可以枚举小于a中最大值的所有数,判断是否为其中若干个数的gcd。记c[k]为a中k的倍数的个数,然后枚举k的倍数i*k,c[i]<2直接跳过,如果c[i*k]==c[k],说明k的那些倍数也同时是i*k的倍数,k就可以不在集合中,反之,如果任意i,c[i*k]<c[k],说明存在一个倍数和其它k的倍数的gcd是k,所以k一定在集合中。两次枚举倍数,复杂度为O(nlogn)。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 const int maxn=1e6+5;
     6 bool In_set[maxn];
     7 int count_multiple[maxn];
     8 int main(){
     9     int n,ans=0,a;
    10     scanf("%d",&n);
    11     ans=n;
    12     memset(In_set,0,sizeof(In_set));
    13     memset(count_multiple,0,sizeof(count_multiple));
    14     for(int i=0;i<n;i++){
    15         scanf("%d",&a);
    16         if(In_set[a])ans--;
    17         In_set[a]=true;
    18     }
    19     for(int i=1;i<maxn;i++){
    20         //if(In_set[i])continue;
    21         for(int j=i;j<maxn;j+=i){
    22             if(In_set[j])
    23                 count_multiple[i]++;
    24         }
    25     }
    26     for(int i=1;i<maxn;i++){
    27         if(In_set[i]||count_multiple[i]<2)continue;
    28         bool ok=true;
    29         for(int j=2*i;j<maxn;j+=i){
    30             if(count_multiple[j]==count_multiple[i]){
    31                 ok=false;break;
    32             }
    33         }
    34         if(ok)
    35             ans++;
    36     }
    37     cout<<ans<<endl;
    38     return 0;
    39 }
  • 相关阅读:
    Docker的历史
    IP路由基础
    Docker的基础知识(二)
    Docker的基础知识(一)
    CentOS7下安装部署“zabbix”
    使用amoeba实现mysql读写分离
    ?? 运算符(C# 参考)
    ?? 运算符(C# 参考)
    knockout,change事件
    knockout,change事件
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7128685.html
Copyright © 2020-2023  润新知