POJ 3904 JZYZOJ 1202 Sky Code 莫比乌斯反演 组合数

 

题意:给一些数,求在这些数中找出四个数互质的方案数。

 
莫比乌斯反演的式子有两种形式http://blog.csdn.net/outer_form/article/details/50588307
这里用的是第二种形式。
求出四个数的公约数为x的倍数的方案数,即可得到,四个数的公约数为x的方案数。
这里x为1。
代码
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int maxn=10010;
 9 const long long modn=1000000007;
10 int n;
11 int a[maxn*10]={};
12 long long cnt[maxn]={},f[maxn]={};
13 long long mic[maxn]={},su[maxn]={},tot=0;
14 bool vis[maxn]={};
15 int main(){
16     mic[1]=1;
17     for(int i=2;i<=maxn;i++){
18         if(!vis[i]){
19             su[++tot]=i;
20             mic[i]=-1;
21         }
22         for(int j=1;j<=tot;j++){
23             int k=i*su[j];
24             if(k>maxn)break;
25             vis[k]=1;
26             if(i%su[j])mic[k]=-mic[i];
27             else break;
28         }
29     }
30     while(~scanf("%d",&n)){
31         int ma=0;memset(cnt,0,sizeof(cnt));
32         for(int i=1;i<=n;i++){
33             scanf("%d",&a[i]);
34             ma=max(a[i],ma);
35             int w=sqrt(double(a[i]));
36             for(int j=1;j<=w;j++){
37                 if(a[i]%j==0){cnt[j]+=1;cnt[a[i]/j]+=1;}
38             }
39             if(w*w==a[i])cnt[w]--;
40         }
41         long long ans=0;
42         for(int i=1;i<=ma;i++){
43             if(cnt[i]<4||mic[i]==0)continue;
44             ans+=mic[i]*cnt[i]*(cnt[i]-1)*(cnt[i]-2)*(cnt[i]-3)/24;
45         }
46         printf("%I64d
",ans);
47     }
48 }
View Code

原文地址:https://www.cnblogs.com/137shoebills/p/7786523.html