This problem is so easy! Can you solve it?
You are given a sequence which contains n integers a1,a2……an, your task is to find how many pair(ai, aj)(i < j) that ai and aj is co-prime.
3 1 2 3
3
思路: http://blog.csdn.net/lyhvoyage/article/details/38455415应该是出题的人吧。
分析:莫比乌斯反演。
此题中,设F(d)表示n个数中gcd为d的倍数的数有多少对,f(d)表示n个数中gcd恰好为d的数有多少对,
则F(d)=∑f(n) (n % d == 0)
f(d)=∑mu[n / d] * F(n) (n %d == 0)
上面两个式子是莫比乌斯反演中的式子。
所以要求互素的数有多少对,就是求f(1)。
而根据上面的式子可以得出f(1)=∑mu[n] * F(n)。
所以把mu[]求出来,枚举n就行了,其中mu[i]为i的莫比乌斯函数。
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 const int N = 1e5+1; 7 8 int vis[N]; 9 int mu[N]; 10 int prime[N],cnt; 11 int date[N]; 12 long long ys[N]; 13 int num[N]; 14 void init() 15 { 16 memset(vis,0,sizeof(vis)); 17 mu[1] = 1; 18 cnt = 0; 19 for(int i=2;i<N;i++) 20 { 21 if(!vis[i]) 22 { 23 prime[cnt++] = i; 24 mu[i] = -1; 25 } 26 for(int j = 0;j<cnt&&i*prime[j]<N;j++) 27 { 28 vis[i*prime[j]] = 1; 29 if(i%prime[j]) mu[i*prime[j]] = -mu[i]; 30 else 31 { 32 mu [i *prime[j]] = 0; 33 break; 34 } 35 } 36 } 37 } 38 int main() 39 { 40 int n,maxn; 41 init(); 42 while(scanf("%d",&n)>0) 43 { 44 memset(num,0,sizeof(num)); 45 memset(ys,0,sizeof(ys)); 46 maxn = -1; 47 for(int i=1;i<=n;i++){ 48 scanf("%d",&date[i]); 49 num[date[i]] ++; 50 if(date[i]>maxn) maxn = date[i]; 51 } 52 /***计算F(N)*/ 53 for(int i=1;i<=maxn;i++) 54 { 55 for(int j=i;j<=maxn;j=j+i) 56 { 57 ys[i] = ys[i] + num[j]; 58 } 59 } 60 long long sum = 0; 61 for(int i=1;i<=maxn;i++){ 62 long long tmp = (long long)ys[i] *( ys[i]-1 )/2; 63 sum = sum + mu[i]*tmp; 64 } 65 66 printf("%I64d\n",sum); 67 } 68 return 0; 69 }
nyoj CO-PRIME 莫比乌斯反演,布布扣,bubuko.com
原文:http://www.cnblogs.com/tom987690183/p/3902399.html