【数论】线性筛&积性函数

线性筛

线性筛素数
#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 &lt; p 2 &lt; (p_1&lt;p_2&lt; (p1<p2< … \ldots &lt; p c ) &lt;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] iprim[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]iprim[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(1p11)(1p21)(1pk1)
即小于等于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 dnϕ(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) (nm) n n n互质(由辗转相除法可知)
n &gt; 2 n&gt; 2 n>2时, ϕ ( n ) \phi(n) ϕ(n)为偶数,也就是说 m m m n − m n-m nm成对出现,有 ϕ ( 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 n2时,该式成立。

线性筛欧拉函数
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),n1012,可用以下筛法

要预处理出 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] dnμ(d)=[n==1]
3: ∑ d ∣ n μ ( d ) d = φ ( n ) n \sum_{d|n}\frac{\mu(d)}{d}=\frac{\varphi(n)}{n} dndμ(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)=dnf(d)
f ( n ) = ∑ d ∣ n μ ( d ) F ( n d ) f(n)=\sum_{d|n}\mu(d)F(\frac{n}{d}) f(n)=dnμ(d)F(dn)
形式二:
F ( n ) = ∑ n ∣ d f ( d ) F(n)=\sum_{n|d}f(d) F(n)=ndf(d)
f ( n ) = ∑ n ∣ d μ ( d n ) F ( d ) f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d) f(n)=ndμ(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] 1a1b[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)=[igcd(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]=idf(d)
f ( i ) = ∑ i ∣ d μ ( d i ) F ( d ) f(i)=\sum_{i|d}\mu(\frac{d}{i})F(d) f(i)=idμ(id)F(d)

逆元函数

模数为m:
a ∗ i n v [ a ] ≡ 1 a*inv[a]\equiv1 ainv[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[ab]=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 ainv[a]1,binv[b]1abinv[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[ab]=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[k1],当前要求 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]ainv[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 &lt; p 2 &lt; (p_1&lt;p_2&lt; (p1<p2< … \ldots &lt; p m ) &lt;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 &lt; p 2 &lt; (p_1&lt;p_2&lt; (p1<p2< … \ldots &lt; p c ) &lt;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(ab)=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 &lt; p 2 &lt; (p_1&lt;p_2&lt; (p1<p2< … \ldots &lt; p c ) &lt;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(ab)=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=iprim[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=0k1p1jj=0k1+1p1j=s(i)p1k1+11p1k1+21
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=iprim[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=0k1p1jj=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))(p1j=0k1p1j+j=0k1p1jp1j=0k11p1j)
= 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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值