zoukankan      html  css  js  c++  java
  • Codeforces 803F

    原题链接:http://codeforces.com/contest/803/problem/F

    题意:若gcd(a1, a2, a3,...,an)=1则认为这n个数是互质的。求集合a中,元素互质的集合的个数。

    思路:首先知道一个大小为n的集合有2n-1个非空子集,运用容斥,对某个数,我们可以求出它作为因子出现的个数(假设为ki)。推一下式子,可以得到结果就等于:Σmiu[i]*(2i-1),其中miu[i]是莫比乌斯函数。

    时间复杂度为:O(n*sqrt(max_a)),看起来似乎会超时,实际上用了不到300ms过了。

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<map>
     5 using namespace std;
     6 typedef long long LL;
     7 const LL MOD=1e9+7;
     8 const int MAXN=1e5+10;
     9 int num[MAXN];
    10 map<int, int> mp;
    11 int miu[MAXN],primes[MAXN],tot=0;
    12 bool isPrime[MAXN];
    13 void getMiu()
    14 {
    15     memset(isPrime,true,sizeof(isPrime));
    16     miu[1]=1;
    17     for(int i=2;i<MAXN;i++)
    18     {
    19         if(isPrime[i])
    20         {
    21             miu[i]=-1;
    22             primes[++tot]=i;
    23         }
    24         for(int j=1;j<=tot;j++)
    25         {
    26             if(i*primes[j]>=MAXN) break;
    27             isPrime[i*primes[j]]=false;
    28             if(i%primes[j]==0)
    29             {
    30                 miu[i*primes[j]]=0;
    31                 break;
    32             }
    33             miu[i*primes[j]]=-miu[i];
    34         }
    35     }
    36 }
    37 LL POW[MAXN];
    38 void getpow()
    39 {
    40     POW[0]=1;
    41     for(int i=1;i<MAXN;i++)
    42         POW[i]=POW[i-1]*2%MOD;
    43     return;
    44 }
    45 int main()
    46 {
    47     int n,a,maxx;
    48     getMiu();
    49     getpow();
    50     scanf("%d", &n);
    51     maxx=0;
    52     for(int i=0;i<n;i++){
    53         scanf("%d", &a);//cout<<'*'<<endl;
    54         maxx=max(a, maxx);
    55         for(int j=1;j*j<=a;j++){
    56             if(a%j==0){ 
    57                 mp[j]++;
    58                 if(j*j!=a)
    59                     mp[a/j]++;
    60             }
    61         }
    62     }
    63     
    64     LL res=0;
    65     for(int i=1;i<=maxx;i++){
    66         if(mp[i]!=0){
    67             res=(res+miu[i]*(POW[mp[i]]-1))%MOD;
    68         }
    69     }
    70     res=(res%MOD+MOD)%MOD;
    71     cout<<res<<endl;
    72 }

    做过多校题HDU6053发现思路差不多,于是一发就AC了特别开心 :D

  • 相关阅读:
    get和post
    java学习day34-Cookie技术
    java学习day33-Maven-相关
    在Linux设置完共享文件夹后无法显示Windows里的文件
    Tomcat-把tomcat的端口号从8080修改为80
    是否忘记向源中添加“#include“StdAfx.h””
    php-fpm配置文件详解
    Web安全常见漏洞修复建议
    blog个性化设置
    使用 notepad++ 编辑器在行首、行尾添加字符
  • 原文地址:https://www.cnblogs.com/MasterSpark/p/7453520.html
Copyright © 2011-2022 走看看