大致内容

线性筛欧拉函数和线性筛素数其实差不多 只是需要用到一些性质: (以下所有p都为素数)

性质1. φ(p)=p1\varphi (p) = p-1

这个比较显然,因为素数p除了1之外的因数只有p,因此1到p的整数只有p和p自己不互质

性质2. 若 ,那么

证明:

b=gcd(n,i)b = gcd(n, i) 因为n、i不互质,所以n=k1b,i=k2bn=k_1b, i=k_2b 所以n+i=(k1+k2)bn +i=(k_1+k_2)b,即n+in+iii不互质

因为[1,i][1,i]中与ii不互质的整数n共有iφ(i)i-\varphi (i)个,且n+in+iii不互质

所以(i,2i](i,2i]中与ii不互质的整数也是iφ(i)i-\varphi (i)

所以[1,ip][1, i*p]中与ii不互质的整数有p(iφ(i))=pipφ(i)p(i - \varphi(i)) = p*i - p*\varphi(i)

φ(ip)=pi(pipφ(i))\varphi(i*p)=p*i-(p*i-p*\varphi(i))

因此φ(ip)=pφ(i)\varphi (i * p) = p * \varphi(i)

2018.12.16 Update

今天再看这个性质2居然看不太懂了。。。

另外一个比较好理解的证明方法:

由于φ\varphi的另外一种计算方法φ(x)=xi(11pi)\varphi(x)=x*\prod_{i}(1-\frac{1}{p_i}) 其中pip_ixx的质因子

且此时ipi|p,即ii已经包含了ipi * p的所有质因子

那么φ(ip)=ipi(11pi)=pφ(i)\varphi(i * p)=i * p * \prod_i(1-\frac{1}{p_i}) = p * \varphi(i)

性质3. 若 pip\nmid i,那么φ(ip)=φ(i)(p1)\varphi(i * p)=\varphi(i) * (p - 1)

由性质1及phi函数为积性函数可知

Code(hdu2824)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;
const int Maxn = 3000000 + 100;
int Prime[Maxn], phi[Maxn], NotPrime[Maxn], Cnt;
int N, a, b;
inline void Get_phi()
{
for (int i = 2; i <= Maxn; ++i)
{
if (!NotPrime[i])
{
Prime[++Cnt] = i;
phi[i] = i - 1;
}
for (int j = 1; j <= Cnt && i * Prime[j] <= Maxn; ++j)
{
NotPrime[i * Prime[j]] = 1;
if (!(i % Prime[j]))
{
phi[i * Prime[j]] = phi[i] * Prime[j];
break;
}
else phi[i * Prime[j]] = phi[i] * (Prime[j] - 1);
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("A.in", "r", stdin);
freopen("A.out", "w", stdout);
#endif
Get_phi();
while (scanf("%d%d", &a, &b) != EOF)
{
LL Ans = 0;
for (int i = a; i <= b; ++i) Ans += phi[i];
cout<<Ans<<endl;
}
return 0;
}