码迷,mamicode.com
首页 > 其他好文 > 详细

hdu.5212.Code(莫比乌斯反演 && 线性筛)

时间:2015-05-04 08:35:42      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:

Code

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 300    Accepted Submission(s): 124

Problem Description
WLD likes playing with codes.One day he is writing a function.Howerver,his computer breaks down because the function is too powerful.He is very sad.Can you help him?
The function:
int calc {      int res=0;      for(int i=1;i<=n;i++)          for(int j=1;j<=n;j++)          {              res+=gcd(a[i],a[j])*(gcd(a[i],a[j])-1);              res%=10007;          }      return res;
}
 

 

Input
There are Multiple Cases.(At MOST 10)
For each case:
The first line contains an integer N(1N10000).
The next line contains N integers a1,a2,...,aN(1ai10000).
 

 

Output
For each case:
Print an integer,denoting what the function returns.
 

 

Sample Input
5
1 3 4 2 4
 

 

Sample Output
64
Hint
gcd(x,y) means the greatest common divisor of x and y.
 
技术分享
 1 #include<stdio.h>
 2 #include<string.h>
 3 int prime[10000 + 10] ;
 4 int a[10000 + 10] ;
 5 int mui[10000 + 10] ;
 6 bool vis[10000 + 10] ;
 7 
 8 int main ()
 9 {
10     memset (prime , 0 , sizeof(prime)) ;
11     memset (mui , 0 , sizeof(mui)) ;
12     memset (vis , 0 , sizeof(vis)) ;
13     for (int i = 1 ; i <= 10000 ; i ++) a[i] = i ;
14     for (int i = 2 ; i <= 10000 ; i ++) {
15         for (int j = i ; j <= 10000 ; j += i ) {
16             if (a[j] % i == 0 && ! vis[j] ) {
17                 int cnt = 0 ;
18                 while (a[j] % i == 0) {
19                     a[j] /= i ;
20                     cnt ++ ;
21                 }
22                 if (cnt > 1) { vis[j] = 1 ; mui[j] = 0 ;}
23                 else mui[j] ++ ;
24             }
25         }
26     }
27   /*  printf ("μ_source:\n") ;
28     for (int i = 2 ; i <= 5 ; i ++) printf ("ID %d: %d\n" , i , mui[i]) ; puts (""); */
29     mui[1] = 1 ;
30     for (int i = 2 ; i <= 10000 ; i++) {
31         if ( mui[i] ) mui[i] = (int) pow (-1 , mui[i]) ;
32     }
33 }
View Code

我从杰哥那里学到了一种和百度上不同的莫比乌斯反演写法(个人感觉不错):
技术分享技术分享

n为d的所有倍数。

则:技术分享

μ(1) = 1 ;

k = p1 * p2 * p3 ……*pr(k由r个不同的质数组成)则μ(k) = -1^k ;

其他情况,μ (k) = 0 ;

这道题F(x)指的是x的倍数的对数的个数有多少。

f(x) = 最大公约数为x的多数有多少。

比如:

F(1) = f(1) + f(2) + f(3) + f(4) = 7 + 2 + 0 + 1 = 10

得到F(x)是非常容易的可以统计x的倍数有多少个,比如说=cnt ;

那么此时的F(x) = (cnt * cnt - cnt) / 2 ;(稍微想想就能想通)

Then , it‘s the time for 。。。。。

hdu.5212.Code(莫比乌斯反演 && 线性筛)

标签:

原文地址:http://www.cnblogs.com/get-an-AC-everyday/p/4475156.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!