This problem is so easy! Can you solve it?ios
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應該是出題的人吧。
分析:莫比烏斯反演。spa
此題中,設F(d)表示n個數中gcd爲d的倍數的數有多少對,f(d)表示n個數中gcd剛好爲d的數有多少對,.net
則F(d)=∑f(n) (n % d == 0)code
f(d)=∑mu[n / d] * F(n) (n %d == 0)htm
上面兩個式子是莫比烏斯反演中的式子。blog
因此要求互素的數有多少對,就是求f(1)。ip
而根據上面的式子能夠得出f(1)=∑mu[n] * F(n)。內存
因此把mu[]求出來,枚舉n就好了,其中mu[i]爲i的莫比烏斯函數。get
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 }