线性筛
线性筛素数
#define MAXN 1000000
int prim[MAXN],vis[MAXN],c;
void Solve()
{
mu[1]=1;
for(int i=2;i<MAXN;i++)
{
if(!vis[i])
prim[c++]=i;
for(int j=0;1LL*prim[j]*i<MAXN;j++)
{
vis[i*prim[j]]=1;
if(i%prim[j]==0)
break;
}
}
}
一些理解:
1.一个合数
A
=
p
1
k
1
p
2
k
2
A=p_1^{k_1}p_2^{k_2}
A=p1k1p2k2
…
\ldots
…
p
c
k
c
p_c^{k_c}
pckc
(
p
1
<
p
2
<
(p_1<p_2<
(p1<p2<
…
\ldots
…
<
p
c
)
<p_c)
<pc)被筛出来时,
p
r
i
m
[
j
]
=
p
1
prim[j]=p_1
prim[j]=p1;
2.当满足 if (
i
i
i%
p
r
i
m
[
j
]
=
=
0
prim[j]== 0
prim[j]==0) break 时,合数
i
∗
p
r
i
m
[
j
]
i*prim[j]
i∗prim[j] 还没有被筛出来。
当
i
1
=
i
p
r
i
m
[
j
]
∗
p
r
i
m
[
j
+
1
]
i_1=\frac{i}{prim[j]}*prim[j+1]
i1=prim[j]i∗prim[j+1],内层循环枚举到
p
r
i
m
[
j
]
prim[j]
prim[j]时,才会被筛出。
##积性函数
###欧拉函数
ϕ
(
n
)
=
∑
i
=
1
n
[
g
c
d
(
i
,
n
)
=
1
]
=
n
∗
(
1
−
1
p
1
)
∗
(
1
−
1
p
2
)
∗
…
∗
(
1
−
1
p
k
)
\phi(n)=\sum_{i=1}^n[gcd(i,n)=1]=n*(1-\frac{1}{p_1})*(1-\frac{1}{p_2})*\ldots*(1-\frac{1}{p_k})
ϕ(n)=∑i=1n[gcd(i,n)=1]=n∗(1−p11)∗(1−p21)∗…∗(1−pk1)
即小于等于x并且和x互质的数的个数
性质
1:(积性函数)
ϕ
(
a
b
)
=
ϕ
(
a
)
ϕ
(
b
)
\phi(ab)=\phi(a)\phi(b)
ϕ(ab)=ϕ(a)ϕ(b),其中gcd(a,b)=1;
2:
∑
d
∣
n
ϕ
(
d
)
=
n
\sum_{d|n}\phi(d)=n
∑d∣nϕ(d)=n
3:小于
n
n
n且与
n
n
n互质的数的和:
s
u
m
=
n
ϕ
(
n
)
2
sum=\frac{n\phi(n)}{2}
sum=2nϕ(n)
证明:显然,若
m
m
m与
n
n
n互质,则
(
n
−
m
)
(n-m)
(n−m)与
n
n
n互质(由辗转相除法可知)
当
n
>
2
n> 2
n>2时,
ϕ
(
n
)
\phi(n)
ϕ(n)为偶数,也就是说
m
m
m与
n
−
m
n-m
n−m成对出现,有
ϕ
(
n
)
2
\frac{\phi(n)}{2}
2ϕ(n)对,此时
s
u
m
=
n
ϕ
(
n
)
2
sum=\frac{n\phi(n)}{2}
sum=2nϕ(n)
当
n
≤
2
n\leq 2
n≤2时,该式成立。
线性筛欧拉函数
int phi[MAXN],prim[MAXN],c;
void Solve()
{
phi[1]=1;
for(int i=2;i<MAXN;i++)
{
if(!phi[i])
{
prim[c++]=i;
phi[i]=i-1;
}
for(int j=0;1LL*prim[j]*i<MAXN;j++)
{
if(i%prim[j]==0)
{
phi[i*prim[j]]=prim[j]*phi[i];
break;
}
phi[i*prim[j]]=(prim[j]-1)*phi[i];
}
}
}
补充:当我们只需要求某一个数的 ϕ ( n ) , n ≤ 1 0 12 \phi(n),n\leq 10^{12} ϕ(n),n≤1012,可用以下筛法
要预处理出
1
0
6
10^6
106以内素数。
时间复杂度:O(
n
\sqrt n
n)
LL Solve(LL n)
{
LL ret=n;
for(int i=0;i<tot&&prim[i]<=n;i++)
if(n%prim[i]==0)
{
ret=ret/prim[i]*(prim[i]-1);
while(n%prim[i]==0) n/=prim[i];
}
if(n!=0) ret=ret/n*(n-1);
return ret;
}
莫比乌斯函数
μ
\mu
μ(1)=1
μ
\mu
μ(d)=
(
−
1
)
k
(-1)^k
(−1)k,
d
=
p
1
p
2
p
3
d=p_1p_2p_3
d=p1p2p3
…
\ldots
…
p
k
p_k
pk,其中 p 为素数
μ
\mu
μ(d)=0,其他
性质
1:(积性函数)
μ
(
a
b
)
=
μ
(
a
)
μ
(
b
)
\mu(ab)=\mu(a)\mu(b)
μ(ab)=μ(a)μ(b),其中gcd(a,b)=1;
2:
∑
d
∣
n
μ
(
d
)
=
[
n
=
=
1
]
\sum_{d|n}\mu(d)=[n==1]
∑d∣nμ(d)=[n==1]
3:
∑
d
∣
n
μ
(
d
)
d
=
φ
(
n
)
n
\sum_{d|n}\frac{\mu(d)}{d}=\frac{\varphi(n)}{n}
∑d∣ndμ(d)=nφ(n)
线性筛莫比乌斯函数
#define MAXN 1000000
int mu[MAXN],prim[MAXN],vis[MAXN],c;
void Solve()
{
mu[1]=1;
for(int i=2;i<MAXN;i++)
{
if(vis[i]==0)
{
prim[c++]=i;
mu[i]=-1;
}
for(int j=0;1LL*prim[j]*i<MAXN;j++)
{
vis[i*prim[j]]=1;
if(i%prim[j]==0)
{
mu[i*prim[j]]=0;
break;
}
mu[i*prim[j]]=-mu[i];
}
}
}
莫比乌斯反演
形式一:
F
(
n
)
=
∑
d
∣
n
f
(
d
)
F(n)=\sum_{d|n}f(d)
F(n)=∑d∣nf(d)
f
(
n
)
=
∑
d
∣
n
μ
(
d
)
F
(
n
d
)
f(n)=\sum_{d|n}\mu(d)F(\frac{n}{d})
f(n)=∑d∣nμ(d)F(dn)
形式二:
F
(
n
)
=
∑
n
∣
d
f
(
d
)
F(n)=\sum_{n|d}f(d)
F(n)=∑n∣df(d)
f
(
n
)
=
∑
n
∣
d
μ
(
d
n
)
F
(
d
)
f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d)
f(n)=∑n∣dμ(nd)F(d)
一些问题 bzoj 3930 选数
1.求
∑
1
a
∑
1
b
[
g
c
d
(
x
,
y
)
=
1
]
\sum_1^a\sum_1^b[gcd(x,y)=1]
∑1a∑1b[gcd(x,y)=1]
令
f
(
i
)
=
∑
[
g
c
d
(
x
,
y
)
=
i
]
f(i)=\sum[gcd(x,y)=i]
f(i)=∑[gcd(x,y)=i],
F
(
i
)
=
∑
[
i
∣
g
c
d
(
x
,
y
)
]
F(i)=\sum[i|gcd(x,y)]
F(i)=∑[i∣gcd(x,y)]
F
(
i
)
=
[
a
i
]
[
b
i
]
=
∑
i
∣
d
f
(
d
)
F(i)=[\frac{a}{i}][\frac{b}{i}]=\sum_{i|d}f(d)
F(i)=[ia][ib]=∑i∣df(d)
f
(
i
)
=
∑
i
∣
d
μ
(
d
i
)
F
(
d
)
f(i)=\sum_{i|d}\mu(\frac{d}{i})F(d)
f(i)=∑i∣dμ(id)F(d)
逆元函数
模数为m:
a
∗
i
n
v
[
a
]
≡
1
a*inv[a]\equiv1
a∗inv[a]≡1
i
n
v
[
a
]
=
a
p
h
i
[
m
]
−
1
inv[a]=a^{phi[m]-1}
inv[a]=aphi[m]−1
性质
1.(完全积性函数,不需要(a,b)=1)在模素数p的意义下:
i
n
v
[
a
∗
b
]
=
i
n
v
[
a
]
∗
i
n
v
[
b
]
inv[a*b]=inv[a]*inv[b]
inv[a∗b]=inv[a]∗inv[b]
证明
在模素数p的意义下:
a
∗
i
n
v
[
a
]
≡
1
,
b
∗
i
n
v
[
b
]
≡
1
⇒
a
∗
b
∗
i
n
v
[
a
]
∗
i
n
v
[
b
]
≡
1
a*inv[a]\equiv1,b*inv[b]\equiv1 \Rightarrow a*b*inv[a]*inv[b]\equiv 1
a∗inv[a]≡1,b∗inv[b]≡1⇒a∗b∗inv[a]∗inv[b]≡1
⇒
i
n
v
[
a
∗
b
]
=
i
n
v
[
a
]
∗
i
n
v
[
b
]
\Rightarrow inv[a*b]=inv[a]*inv[b]
⇒inv[a∗b]=inv[a]∗inv[b]
线性筛逆元函数
Solution1:(P为素数)
int inv[MAXN],prim[MAXN],c,P;
void Solve()
{
inv[1]=1;
for(int i=2;i<MAXN;i++)
{
if(inv[i]==0)
{
prim[c++]=i;
inv[i]=PowMod(i,P-2);
}
for(int j=0;1LL*prim[j]*i<MAXN;j++)
{
inv[i*prim[j]]=inv[i]*inv[prim[j]];
if(i%prim[j]==0)
break;
}
}
}
Solution2:(P为素数)
void Solve()
{
inv[1]=1;
for(int i=2;i<P;i++)
inv[i]=1LL*(P-P/i)*inv[P%i]%P;
}
证明:
i
n
v
[
1
]
=
1
inv[1]=1
inv[1]=1
假设当前已经求出
i
n
v
[
1
]
,
i
n
v
[
2
]
,
…
,
i
n
v
[
k
−
1
]
inv[1],inv[2],\ldots,inv[k-1]
inv[1],inv[2],…,inv[k−1],当前要求
i
n
v
[
k
]
inv[k]
inv[k].
∵
P
=
[
P
k
]
∗
k
+
\because P=[\frac{P}{k}]*k+
∵P=[kP]∗k+P%k;
令 a=P%k ,有
a
=
P
−
[
P
k
]
∗
k
a=P-[\frac{P}{k}]*k
a=P−[kP]∗k;
又
∵
i
n
v
[
a
]
∗
a
≡
i
n
v
[
a
]
∗
(
P
−
[
P
k
]
∗
k
)
≡
i
n
v
[
a
]
∗
(
−
[
P
k
]
∗
k
)
≡
1
\because inv[a]*a\equiv inv[a]*(P-[\frac{P}{k}]*k)\equiv inv[a]*(-[\frac{P}{k}]*k)\equiv1
∵inv[a]∗a≡inv[a]∗(P−[kP]∗k)≡inv[a]∗(−[kP]∗k)≡1
∴
i
n
v
[
k
]
=
i
n
v
[
a
]
∗
(
−
[
P
k
]
)
\therefore inv[k]=inv[a]*(-[\frac{P}{k}])
∴inv[k]=inv[a]∗(−[kP])
补充:求阶乘的逆元
void Solve()
{
fac[0]=1;
for(int i=1;i<=n;i++)
fac[i]=1LL*fac[i-1]*i%P;
inv[n]=PowMod(fac[n],P-2);
for(int i=n-1;i>=0;i--)
inv[i]=1LL*(i+1)*inv[i+1]%P;
}
线性筛 g c d ( a , b ) , b gcd(a,b),b gcd(a,b),b为定值
令 g [ i ] = g c d ( i , b ) , e k [ i ] = p 1 k 1 g[i]=gcd(i,b),ek[i]=p_1^{k_1} g[i]=gcd(i,b),ek[i]=p1k1,其中, i = p 1 k 1 p 2 k 2 i=p_1^{k_1}p_2^{k_2} i=p1k1p2k2 … \ldots … p m k m p_m^{k_m} pmkm ( p 1 < p 2 < (p_1<p_2< (p1<p2< … \ldots … < p m ) <p_m) <pm)
int g[MAXN],ek[MAXN],prim[MAXN],c,P,b;
void Solve()
{
g[1]=1;
for(int i=2;i<MAXN;i++)
{
if(g[i]==0)
{
prim[c++]=i;
g[i]=max((b%i==0)*i,1);
ek[i]=i;
}
for(int j=0;1LL*prim[j]*i<MAXN;j++)
{
if(i%prim[j]==0)
{
ek[i*prim[j]]=ek[i]*ek[prim[j]];
if(b%(ek[i]*prim[j])==0) g[i*prim[j]]=g[i]*prim[j];
else g[i*prim[j]]=g[i];
break;
}
ek[i*prim[j]]=prim[j];
g[i*prim[j]]=g[i]*g[prim[j]];
}
}
}
n n n的正因子数目 d ( n ) d(n) d(n)
n
=
p
1
k
1
p
2
k
2
n=p_1^{k_1}p_2^{k_2}
n=p1k1p2k2
…
\ldots
…
p
c
k
c
p_c^{k_c}
pckc
(
p
1
<
p
2
<
(p_1<p_2<
(p1<p2<
…
\ldots
…
<
p
c
)
<p_c)
<pc)
d
(
n
)
=
∏
i
=
1
c
(
k
i
+
1
)
d(n)=\prod_{i=1}^c (k_i+1)
d(n)=∏i=1c(ki+1)
记
e
(
n
)
=
k
1
e(n)=k_1
e(n)=k1
性质
1.(积性函数)
d
(
a
∗
b
)
=
d
(
a
)
∗
d
(
b
)
d(a*b)=d(a)*d(b)
d(a∗b)=d(a)∗d(b),其中
g
c
d
(
a
,
b
)
=
1
gcd(a,b)=1
gcd(a,b)=1
线性筛 d ( n ) d(n) d(n)
int d[MAXN],e[MAXN],prim[MAXN],c;
void Solve()
{
g[1]=1;
for(int i=2;i<MAXN;i++)
{
if(d[i]==0)
{
prim[c++]=i;
d[i]=2;
e[i]=1;
}
for(int j=0;1LL*prim[j]*i<MAXN;j++)
{
if(i%prim[j]==0)
{
d[i*prim[j]]=d[i]/(e[i]+1)*(e[i]+2);
e[i*prim[j]]=e[i]+1;
break;
}
d[i*prim[j]]=d[i]*d[prim[j]];
e[i*prim[j]]=1;
}
}
}
n n n的正因子之和 s ( n ) s(n) s(n)
n
=
p
1
k
1
p
2
k
2
n=p_1^{k_1}p_2^{k_2}
n=p1k1p2k2
…
\ldots
…
p
c
k
c
p_c^{k_c}
pckc
(
p
1
<
p
2
<
(p_1<p_2<
(p1<p2<
…
\ldots
…
<
p
c
)
<p_c)
<pc)
s
(
n
)
=
∏
i
=
1
c
(
∑
j
=
0
k
i
p
i
j
)
s(n)=\prod_{i=1}^c (\sum_{j=0}^{k_i}p_i^j)
s(n)=∏i=1c(∑j=0kipij)
性质
1.(积性函数)
s
(
a
∗
b
)
=
s
(
a
)
∗
s
(
b
)
s(a*b)=s(a)*s(b)
s(a∗b)=s(a)∗s(b),其中
g
c
d
(
a
,
b
)
=
1
gcd(a,b)=1
gcd(a,b)=1
线性筛 s ( n ) s(n) s(n)
Solution1:
令
n
=
i
∗
p
r
i
m
[
j
]
n=i*prim[j]
n=i∗prim[j],当
p
r
i
m
[
j
]
prim[j]
prim[j]是
i
i
i的最小质因子时:
s
(
n
)
=
(
∏
i
=
2
c
(
∑
j
=
0
k
i
p
i
j
)
)
∗
(
∑
j
=
0
k
1
+
1
p
1
j
)
=
s
(
i
)
∗
∑
j
=
0
k
1
+
1
p
1
j
∑
j
=
0
k
1
p
1
j
=
s
(
i
)
∗
p
1
k
1
+
2
−
1
p
1
k
1
+
1
−
1
s(n)=(\prod_{i=2}^c(\sum_{j=0}^{k_i}p_i^j))*(\sum_{j=0}^{k_1+1}p_1^j)=s(i)*\frac{\sum_{j=0}^{k_1+1}p_1^j}{\sum_{j=0}^{k_1}p_1^j}=s(i)*\frac{p_1^{k1+2}-1}{p_1^{k1+1}-1}
s(n)=(∏i=2c(∑j=0kipij))∗(∑j=0k1+1p1j)=s(i)∗∑j=0k1p1j∑j=0k1+1p1j=s(i)∗p1k1+1−1p1k1+2−1
记
p
e
(
i
)
=
p
1
k
1
+
1
,
p
e
(
n
)
=
p
1
k
1
+
2
pe(i)=p_1^{k_1+1},pe(n)=p_1^{k_1+2}
pe(i)=p1k1+1,pe(n)=p1k1+2
则
s
(
n
)
=
s
(
i
)
∗
p
e
(
n
)
−
1
p
e
(
i
)
−
1
s(n)=s(i)*\frac{pe(n)-1}{pe(i)-1}
s(n)=s(i)∗pe(i)−1pe(n)−1
LL s[MAXN],pe[MAXN];
int prim[MAXN],c;
void Solve()
{
s[1]=1;
for(int i=2;i<MAXN;i++)
{
if(!s[i])
{
prim[c++]=i;
s[i]=i+1;
pe[i]=i*i;
}
for(int j=0;1LL*prim[j]*i<MAXN;j++)
{
if(i%prim[j]==0)
{
pe[i*prim[j]]=pe[i]*prim[j];
s[i*prim[j]]=s[i]/(pe[i]-1)*(pe[i*prim[j]]-1)
break;
}
s[i*prim[j]]=s[i]*s[prim[j]];
pe[i*prim[j]]=pe[prim[j]];
}
}
}
Solution 2:
令
n
=
i
∗
p
r
i
m
[
j
]
n=i*prim[j]
n=i∗prim[j],当
p
r
i
m
[
j
]
prim[j]
prim[j]是
i
i
i的最小质因子时:
s
(
n
)
=
(
∏
i
=
2
c
(
∑
j
=
0
k
i
p
i
j
)
)
∗
(
∑
j
=
0
k
1
+
1
p
1
j
)
s(n)=(\prod_{i=2}^c(\sum_{j=0}^{k_i}p_i^j))*(\sum_{j=0}^{k_1+1}p_1^j)
s(n)=(∏i=2c(∑j=0kipij))∗(∑j=0k1+1p1j)
=
(
∏
i
=
2
c
(
∑
j
=
0
k
i
p
i
j
)
)
∗
(
∑
j
=
1
k
1
+
1
p
1
j
+
∑
j
=
0
k
1
p
1
j
−
∑
j
=
1
k
1
p
1
j
)
=(\prod_{i=2}^c(\sum_{j=0}^{k_i}p_i^j))*(\sum_{j=1}^{k_1+1}p_1^j+\sum_{j=0}^{k_1}p_1^j-\sum_{j=1}^{k_1}p_1^j)
=(∏i=2c(∑j=0kipij))∗(∑j=1k1+1p1j+∑j=0k1p1j−∑j=1k1p1j)
=
(
∏
i
=
2
c
(
∑
j
=
0
k
i
p
i
j
)
)
∗
(
p
1
∗
∑
j
=
0
k
1
p
1
j
+
∑
j
=
0
k
1
p
1
j
−
p
1
∗
∑
j
=
0
k
1
−
1
p
1
j
)
=(\prod_{i=2}^c(\sum_{j=0}^{k_i}p_i^j))*(p_1*\sum_{j=0}^{k_1}p_1^j+\sum_{j=0}^{k_1}p_1^j-p_1*\sum_{j=0}^{k_1-1}p_1^j)
=(∏i=2c(∑j=0kipij))∗(p1∗∑j=0k1p1j+∑j=0k1p1j−p1∗∑j=0k1−1p1j)
=
s
(
i
)
∗
(
p
1
+
1
)
−
s
(
i
p
1
)
∗
p
1
=s(i)*(p_1+1)-s(\frac{i}{p_1})*p_1
=s(i)∗(p1+1)−s(p1i)∗p1
LL s[MAXN];
int prim[MAXN],c;
void Solve()
{
s[1]=1;
for(int i=2;i<MAXN;i++)
{
if(s[i]==0)
{
prim[c++]=i;
s[i]=i+1;
}
for(int j=0;1LL*prim[j]*i<MAXN;j++)
{
if(i%prim[j]==0)
{
s[i*prim[j]]=s[i]*(prim[j]+1)-s[i/prim[j]]*prim[j];
break;
}
s[i*prim[j]]=s[i]*s[prim[j]];
}
}
}
补充题目
模板题
CQOI 3512 筛法求素数表
CQOI 3515 乘法逆元表
CQOI 2710 欧拉函数的值
POJ 2478 Farey Sequence
51Nod 1240 莫比乌斯函数
模板变式
HDU 3501 Calculation:利用欧拉函数性质3
POJ 3090 Visible Lattice Points
HDU 5317 RGCDQ