# 读贾志鹏线性筛有感 (莫比乌斯函数的应用)

f(1) = 1 。 这个在我们高中数学题。抽象函数。就已经能简单知道了。

P = nt + k

n'  ≡ n*(t^2)*f(k)^2 (mod P)

#include<stdio.h>
#include<string.h>
#define    N 100

bool mark[N+5];
int prime[N+5];
int num;
int euler[N+5];
int Min(int a,int b){return a>b?a:b;}
void Euler()
{
int i,j;
num = 0;
memset(euler,0,sizeof(euler));
memset(prime,0,sizeof(prime));
memset(mark,0,sizeof(mark));
euler[1] = 1; // multiply function
for(i=2;i<=N;i++)
{
if(!mark[i])
{
prime[num++] = i;
euler[i] = i-1;
}
for(j=0;j<num;j++)
{
if(i*prime[j]>N){break;}
mark[i*prime[j]] = 1;
if(i%prime[j]==0)
{
euler[i*prime[j]] = euler[i]*prime[j];
break;
}
else
{
euler[i*prime[j]] = euler[prime[j]]*euler[i];
}
}
}
}

int main()
{
int i;
int M1,M2;
Euler();
for(i=0;i<num;i++)printf("%d ",prime[i]);
printf("\n");
for(i=1;i<=N;i++)printf("%d ",euler[i]);
printf("\n");
M1 = 2;
M2 = 3;
int sum = 0;
int min = Min(M1,M2);
for(i=1;i<=min;i++)
{
sum += euler[i]*(M1/i)*(M2/i);
}
printf("%d\n",sum);
}
the second problem test

#include<stdio.h>
#include<string.h>
#define    N 100

bool mark[N+5];
int prime[N+5];
int num;
int mobi[N+5];
int Min(int a,int b){return a>b?a:b;}
void Mobi()
{
int i,j;
num = 0;
memset(mobi,0,sizeof(mobi));
memset(prime,0,sizeof(prime));
memset(mark,0,sizeof(mark));
mobi[1] = 1; // multiply function
for(i=2;i<=N;i++)
{
if(!mark[i])
{
prime[num++] = i;
mobi[i] = -1;
}
for(j=0;j<num;j++)
{
if(i*prime[j]>N){break;}
mark[i*prime[j]] = 1;
if(i%prime[j]==0)
{
mobi[i*prime[j]] = 0;
break;
}
else
{
mobi[i*prime[j]] = mobi[prime[j]]*mobi[i];
}
}
}
}

int main()
{
int i;
int M1,M2;
Mobi();
for(i=0;i<num;i++)printf("%d ",prime[i]);
printf("\n");
for(i=1;i<=N;i++)printf("%d ",mobi[i]);
printf("\n");
M1 = 2;
M2 = 3;
int sum = 0;
int min = Min(M1,M2);
for(i=1;i<=min;i++)
{
sum += mobi[i]*(M1/i)*(M2/i);
}
printf("%d\n",sum);
}
Test problem forth

.

f(n)是积性的。具体证明如论文上解释。

g(kx)=μ(x)                 k|p

g(kx)=μ(x)-g(x)          k!|p

给你个例子。筛一个数的素因子之和。

F[i*prime[j]] = F[i]+prime[j]                            i\prime[j]时。

F[i*prime[j]] = F[i]+prime[j]                             i!\prime[j]时。

F[i*prime[j]] = F[i]                                             i\prime[j]时。

F[i*prime[j]] = F[i]+prime[j]                             i!\prime[j]时。

#include<stdio.h>
#include<string.h>
#define N 100

int num,prime[N+5],f[N+5];
bool mark[N+5];
void Init()
{
int i,j;
num = 0;
f[1] = 0;
for(i=2;i<=N;i++)
{
if(!mark[i])
{
prime[num++] = i;
f[i] = i;
}

for(j=0;j<num;j++)
{
if(i*prime[j]>N){break;}
mark[i*prime[j]] = 1;
if(i%prime[j]==0)
{
f[i*prime[j]] = f[i];
break;
}
else
{
f[i*prime[j]] = f[i]+prime[j];
}
}

}
}

int main()
{
int i;
Init();
for(i=1;i<=N;i++)
{
printf("%d = %d \n",i,f[i]);
}
}
Problem test

i\prime[j]时。

情况1: （i/prime[j]）\prime[j]时.

F[i*prime[j]] = F[i]

情况2： （i/prime[j]）！\prime[j]时.

FF[i*prime[j]] = F[i]-prime[j].

i!\prime[j]时。

F[i*prime[j]] = F[i]+prime[j]

#include<stdio.h>
#include<string.h>
#define N 100

int num,prime[N+5],f[N+5];
bool mark[N+5];
int Max(int a,int b)
{
return a>b?a:b;
}
void Init()
{
int i,j;
num = 0;
f[1] = 0;
for(i=2;i<=N;i++)
{
if(!mark[i])
{
prime[num++] = i;
f[i] = i;
}

for(j=0;j<num;j++)
{
if(i*prime[j]>N){break;}
mark[i*prime[j]] = 1;
if(i%prime[j]==0)
{
if((i/prime[j])%prime[j]==0)
{
f[i*prime[j]] = f[i];
}
else
{
f[i*prime[j]] = f[i] - prime[j];
}

break;
}
else
{
f[i*prime[j]] = f[i]+prime[j];
}
}

}
}

int main()
{
int i;
Init();
for(i=1;i<=N;i++)
{
printf("%d = %d \n",i,f[i]);
}
}
Problem test

扩展问题1: T组N.求1~N范围上与N互素的数的和。

Code:

#include<stdio.h>
#include<string.h>
#define N 100
int num;
int prime[N+5];
int mobius[N+5];
bool mark[N+5];

void Mobius()
{
int i,j;
num = 0;
mobius[1] = 1;

for(i=2;i<=N;i++)
{
if(!mark[i])
{
prime[num++] = i;
mobius[i] = -1;
}
for(j=0;j<num;j++)
{
if(i*prime[j]>N){break;}
mark[i*prime[j]] = 1;
if(i%prime[j]==0)
{
mobius[i*prime[j]] = 0;
}
else
{
mobius[i*prime[j]] = -mobius[i];
}
}
}
}
int solve(int n)
{
int i,r;
r = 0;
for(i=1;i<=n;i++)
{
if(n%i==0)
{
r += mobius[i]*i*(n/i)*(n/i+1);
}
}
r /= 2;
return r;
}
int main()
{
int i,n;
Mobius();
while(scanf("%d",&n)!=EOF)
{
printf("%d = %d\n",n,solve(n));
}
}
Problem two

实际上求互质数和有 n*φ(n)/2 。

上面公式得证。十分感谢yzq986的留言。告诉了我后续的解法！！！~~~

对于互质数我们探讨得较多了。个数（欧拉函数）。互素数和。就是以上的。

 for(int i=1,last;i<=n;i=last+1)
{
last = min(n/(n/i),m/(m/i));
ans += (n/i)*(m/i)*(sum[last]-sum[i-1]);
}  

posted @ 2015-05-04 21:02 Milkor 阅读(...) 评论(...) 编辑 收藏