acw数学知识

本文介绍了数论的基本概念,包括质数的判定(试除法、线性筛)、约数的计算(试除法、约数个数、约数之和)以及欧拉函数的定义、计算方法(欧拉筛)。同时讨论了欧拉定理、快速幂算法、乘法逆元和扩展欧几里得算法,以及线性同余方程和中国剩余定理的应用。这些理论在密码学、算法设计等领域有广泛应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数论基础知识

1. 质数

质数:在大于1的整数中,只包含1和它本身这两个约数的数。
nnn中最多只包含一个大于sqrt(n)sqrt(n)sqrt(n)的质因子。

1.1 质数的判定

试除法 O(sqrt(n))O( sqrt(n) )O(sqrt(n))

bool isPrime(int n)
{
	if(n<2) return false;
	for(int i=2;i<=n/i;i++)
		if(n%i==0)
			return false;
	return true;
}
1.2 分解质因数

试除法 O(log(n))O( log(n) )O(log(n))~O(sqrt(n))O( sqrt (n) )O(sqrt(n))

void divide(int n)
{
	for(int i=2;i<=n/i;i++)
		if(n%i==0)//i一定是质数
		{
			int s=0;
			while(n%i==0)
			{
				n/=i;
				s++;
			}
			printf("%d^%d",i,s);
			if(n!=1) printf(" * ");
		}
	if(n>1) printf("%d^%d\n",n,1);
}
1.3 筛质数
1.3.1 朴素筛法
int prime[N],pNum;
bool p[N];
void find_prime(int n)
{
	for(int i=2;i<=n;i++)
	{
		if(!p[i])
		{
			prime[pNum++]=i;
			for(int j=i+i;j<=n;j+=i)
				p[j]=true;
		}
	}
}
1.3.2 线性筛(欧拉筛)
int prime[N],pNum;
bool p[N];
void find_prime(int n)
{
	for(int i=2;i<=n;i++)
	{
		if(!p[i])
			prime[pNum++]=i;
		for(int j=0;prime[j]<=n/i;j++)//从小到大枚举最小质数
		{
			p[prime[j]*i]=true;
			if(i%prime[j]==0) break;//prime[j]一定是i的最小质因子
		}
	}
}

2. 约数

2.1 试除法求所有约数
vector<int> get_divisors(int n)
{
	vector<int> res;
	for(int i=1;i<=n/i;i++)
	{
		if(n%i==0)
		{
			res.push_back(i);
			if(i!=n/i) res.push_back(n/i);
		}
	}
	sort(res.begin(),res.end());
	return res;
}
int main()
{
	int n;cin>>n;
	auto res=get_divisors(n);
	for(auto t:res) printf("%d ",t);
}
2.2 约数个数

NNN质因数分解

NNN=p1α1p_1^{α_1}p1α1p2α2p_2^{α_2}p2α2p3α3p_3^{α_3}p3α3pnαnp_n^{α_n}pnαn

其中ppp为质数,1~NNNpip_ipi的倍数有pi0p_i^{0}pi0,pi1p_i^{1}pi1piαip_i^{α_i}piαi

约数个数=(α1α_1α1+1)(α2α_2α2+1)(α3α_3α3+1)(αnα_nαn+1)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int main()
{
	int n;cin>>n;
	unordered_map<int,int> primes;
	for(int i=2;i<=n/i;i++)
	{
		while(n%i==0) 
		{
			n/=i;primes[i]++;
		}
	}
	if(n>1) primes[n]++;
	ll res=1;
	for(auto prime:primes) 
		res=res*(prime.second+1)%mod;
	printf("%lld\n",res);
	return 0;
}
2.3 约数之和

约数之和= (p10p_1^{0}p10+p11p_1^{1}p11+p12p_1^{2}p12p1α1p_1^{α_1}p1α1)(p20p_2^{0}p20+p21p_2^{1}p21+p22p_2^{2}p22p2α1p_2^{α_1}p2α1) …(pn0p_n^{0}pn0+pn1p_n^{1}pn1+pn2p_n^{2}pn2pnαnp_n^{α_n}pnαn

ttt=1

ttt=p1p_1p1+1

ttt=p1p_1p1*( p1α1−2p_1^{α_1-2}p1α12+…+ p10p_1^{0}p10 )+1

ttt=p1p_1p1* ( p1p_1p1*( p1α1−2p_1^{α_1-2}p1α12+…+ p10p_1^{0}p10 )+1 ) +1

ttt=p1α1p_1^{α_1}p1α1+…+ p12p_1^{2}p12+p11p_1^{1}p11+p10p_1^{0}p10

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int main()
{
	int n;cin>>n;
	unordered_map<int,int> primes;
	for(int i=2;i<=n/i;i++)
	{
		while(n%i==0) 
		{
			n/=i;primes[i]++;
		}
	}
	if(n>1) primes[n]++;
	ll res=1;
	for(auto prime:primes) 
	{
		int p=prime.first,a=prime.second;
		ll t=1;
		while(a--) t=(t*p+1)%mod;
		res=res*t%mod;
	}	 
	printf("%lld\n",res);
	return 0;
}
2.4 最大公约数(欧几里得算法)

ddd可以整数aaa,ddd可以整数bbb,那么ddd可以整数a∗x+b∗ya*x+b*yax+by

0除以任何一个数都等于0,所以任何数都可以整除0

int gcd(int a,int b)
{
	return b?gcd(b,a%b):a;
}
2.5 最小公倍数
int lcm(int a,int b)
{
	return a/gcd(a,b)*b;
}

3. 欧拉函数

3.1 定义

定义 1~NNN中与NNN互质的数的个数被称为欧拉函数
N= p1α1p_1^{α_1}p1α1 p2α2p_2^{α_2}p2α2 ··· pkαkp_k^{α_k}pkαk

Φ(N)\Phi (N)Φ(N)=N(1-1p1\frac{1}{p_1}p11)(1-1p2\frac{1}{p_2}p21)···(1-1pk\frac{1}{p_k}pk1

3.2 证明
3.2.1 证明

根据容斥原理
Φ(N)\Phi(N)Φ(N)=NNN
-Np1\frac{N}{p_1}p1N -Np2\frac{N}{p_2}p2N -···- Npk\frac{N}{p_k}pkN
+Np1∗p2\frac{N}{p_1*p_2}p1p2N+Np1∗p3\frac{N}{p_1*p_3}p1p3N +···+Npk−1∗pk\frac{N}{p_{k-1}*p_{k}}pk1pkN
-Np1∗p2∗p3\frac{N}{p_1*p_2*p_3}p1p2p3N -Np1∗p2∗p4\frac{N}{p_1*p_2*p_4}p1p2p4N -···-Npk−2∗pk−1∗pk\frac{N}{p_{k-2}*p_{k-1}*p_{k}}pk2pk1pkN
+Np1∗p2∗p3∗p4\frac{N}{p_1*p_2*p_3*p_4}p1p2p3p4N+Np1∗p2∗p3∗p5\frac{N}{p_1*p_2*p_3*p_5}p1p2p3p5N+··· Npk−3∗pk−2∗pk−1∗pk\frac{N}{p_{k-3}*p_{k-2}*p_{k-1}*p_k}pk3pk2pk1pkN

3.2.2代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int res=n;
	for(int i=2;i<=n/i;i++)
	{
		if(n%i==0)
		{
			res=res/i*(i-1);//(a-1)/a 
			while(n%i==0) n/=i;
		}
		if(n>1) res=res/n*(n-1);
	}
	cout<<res<<endl;
	return 0;
}
3.3筛法求欧拉函数

3.3.1推导
(1)iii为质数,ϕ(i)\phi ( i )ϕ(i)= iii - 1
(2)iii modmodmod pjp_jpj ==0==0==0 时,ϕ(pj∗i)\phi( p_j * i )ϕ(pji) = pjp_jpj * ϕ(i)\phi( i )ϕ(i)
(3)iii modmodmod pjp_jpj !=0!= 0!=0 时,ϕ(pj∗i)\phi(p_j * i)ϕ(pji)= ϕ(pj)\phi (p_j)ϕ(pj) * ϕ(i)\phi( i )ϕ(i) = ϕ(i)\phi ( i )ϕ(i) * (pjp_jpj-1)

3.3.2代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int primes[N],cnt;
int phi[N];
bool p[N];

ll get_eulers(int n)
{
	phi[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(!p[i])
		{
			primes[cnt++]=i;
			phi[i]=i-1;
		}	
		for(int j=0;primes[j]<=n/i;j++)
		{
			p[primes[j]*i]=true;
			if(i%primes[j]==0) 
			{
				phi[primes[j]*i]=phi[i]*primes[j];
				break;	
			}
			phi[primes[j]*i]=phi[i]*(primes[j]-1);
		}
	}
	ll res=0;
	for(int i=1;i<=n;i++) res+=phi[i];
	return res;
}
int main()
{
	int n;cin>>n;
	cout<<get_eulers(n)<<endl;
}

4.欧拉定理

4.1 定理

欧拉定理(Euler Theorem,也称费马-欧拉定理或欧拉函数定理):
a,ma,ma,m ∈∈ N+N^{+}N+,且 gcd(a,m)==1gcd (a,m) == 1gcd(a,m)==1,我们有
aϕ(m)a^{\phi(m)}aϕ(m) ≡1≡11 (mod(mod(mod mmm)

4.2 证明

a,na ,na,n互质
1−n1-n1n中,有a1a_1a1,a2a_2a2···,aϕ(n)a_{\phi(n)}aϕ(n)ϕ(n){\phi(n)}ϕ(n)个数与n互质
那么,a*a1a_1a1 , a*a2a_2a2 ,···, a*aϕ(n)a_{\phi(n)}aϕ(n)也与n互质

( aa1a_1a1 modmodmod nnn ) (aa2a_2a2 modmodmod nnn)··· (aaϕ(n)a_{\phi(n)}aϕ(n) modmodmod nnn)
=( aa1a_1a1 * aa2a_2a2 ··· aaϕ(n)a_{\phi(n)}aϕ(n)) modmodmod nnn
=aϕ(n)a^{\phi(n)}aϕ(n) (a1a_1a1a2a_2a2···aϕ(n)a_{\phi(n)}aϕ(n)) modmodmod nnn

aϕ(n)a^{\phi(n)}aϕ(n) (a1a_1a1a2a_2a2···aϕ(n)a_{\phi(n)}aϕ(n)) ≡ a1a_1a1a2a_2a2···aϕ(n)a_{\phi(n)}aϕ(n)modmodmod nnn
所以,aϕ(n)a^{\phi(n)}aϕ(n) ≡ 1 (modmodmod nnn )

4.3 简单推论

费马小定理: 当n是质数时,aϕ(p)a^{\phi(p)}aϕ(p) ≡ 1 (mod p) ,即ap−1a^{p-1}ap1 ≡1≡ 11 (mod(mod(mod p)p)p)

5. 快速幂

5.1 推导

αk\alpha^{k}αk
=α2x1\alpha^{2^{x_{1}}}α2x1 * α2x2\alpha^{2^{x_{2}}}α2x2 ··· α2xk\alpha^{2^{x_{k}}}α2xk
=α2x1+2x2+⋅⋅⋅+2xt\alpha^{2^{x_{1}} + 2^{x_{2}} +···+ 2^{x_{t}}}α2x1+2x2+⋅⋅⋅+2xt
即k=2x12^{x_{1}}2x1+2x22^{x_{2}}2x2+···+2xt2^{x_{t}}2xt

α1\alpha^{1}α1
α21\alpha^{2^{1}}α21=α20\alpha^{2^{0}}α20 * α20\alpha^{2^{0}}α20
α22\alpha^{2^{2}}α22=α21\alpha^{2^{1}}α21 * α21\alpha^{2^{1}}α21
···
α2log2k\alpha^{2^{log_2k}}α2log2k=α2log2k−1\alpha^{2^{log_2k-1}}α2log2k1 * α2log2k−1\alpha^{2^{log_2k-1}}α2log2k1

例:454^545=4(101)24^{(101)_2}4(101)2=404^040 * 424^242
a=4,k=5,p=10,res=1a = 4 , k = 5 , p = 10 , res =1a=4,k=5,p=10,res=1
res=res∗ares = res * ares=resa modmodmod p;p;p;
k>>=1;k >> = 1 ;k>>=1;
a=a∗aa=a*aa=aa modmodmod ppp;

5.2 代码
typedef long long ll;
//返回a^k mod p
int qmi(int a,int k,int p)
{
	int res=1;
	while(k)
	{
		if(k&1) res=(ll)res*a%p; 
		k>>=1;
		a=(ll)a*a%p;
	}
	return res;
}

6. 逆元

6.1 乘法逆元

定义 若整数b,mb,mb,m互质,并且b∣ab|aba,则存在一个整数xxx,使得a/ba/ba/b ≡a∗x≡ a*xax (mod(mod(mod m)m)m),则称xxxbbb的模mmm乘法逆元,记为b−1b^{-1}b1 (modmodmod mmm)。
bbb 存在乘法逆元 <==><==><==> bbbmmm互质
根据费马小定理,当mmm为质数时,bm−2b^{m-2}bm2即为bbb的乘法逆元。
b∗xb*xbx ≡1≡ 11 (mod(mod(mod m)m)m)
bm−1b^{m-1}bm1 ≡1≡ 11 (mod(mod(mod m)m)m)
b∗bm−2b*b^{m-2}bbm2 ≡1≡ 11 (mod(mod(mod m)m)m)
−−>-->> xxx === bm−2b^{m-2}bm2

7. 扩展欧几里得

7.1 裴蜀定理

定理a,ba,ba,b是整数,且 gcd(a,b)=dgcd(a,b)=dgcd(a,b)=d,那么对于任意的整数x,yx,yx,ya∗x+b∗ya*x+b*yax+by 都一定是ddd的倍数。特别地,一定存在整数x,yx,yx,y,使a∗x+b∗y=da*x+b*y=dax+by=d 成立。
证明
因为d∣a,d∣b,d|a,d|b,da,db, 所以d∣(ax+by)d|(ax+by)d(ax+by)

7.2 扩展欧几里得

证明
a∗x1+b∗y1=gcd(a,b)a*x_1+b*y_1=gcd(a,b)ax1+by1=gcd(a,b)
b∗x2+(ab*x_2+(abx2+(a modmodmod b)∗y2b)*y_2b)y2 =gcd(b,a= gcd(b,a=gcd(b,a modmodmod b)b)b)
因为 gcd(a,b)gcd(a,b)gcd(a,b) === gcd(b,gcd(b,gcd(b, aaa modmodmod b)b)b)
其中,aaa modmodmod bbb =a−=a-=a ⌊a/b⌋\lfloor a/b \rfloora/b∗b*bb
那么,b∗x2+b*x_2+bx2+(a modmodmod b)∗y2b)*y_2b)y2
=b∗x2+=b*x_2+=bx2+(a-⌊ab⌋\lfloor \frac{a}{b} \rfloorba∗b)∗y2*b)*y_2b)y2
=a∗y2=a*y_2=ay2+++b∗(x2b*(x_2b(x2 -⌊ab⌋\lfloor \frac{a}{b} \rfloorba*y2y_2y2)))

推得
x1=y2x_1=y_2x1=y2
y1=y_1=y1= x2x_2x2 −- ⌊ab⌋\lfloor \frac{a}{b} \rfloorba*y2y_2y2

int exgcd(int a,int b,int &x,int &y)
{
	if(!b) 
	{
		x=1,y=0;
		return a;
	}
	int d=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return d; 
}
int main()
{
	int a,b,x,y;
	scanf("%d%d",&a,&b);
	exgcd(a,b,x,y);
	printf("%d %d\n",x,y);
	return 0;
}

8. 线性同余方程

给定a,b,ma,b,ma,b,m,求xxx,使得a∗x≡ba*x≡baxb (mod(mod(mod m)m)m)

∃\exists yyy ∈\in ZZZst.st.st. a∗x≡a*x≡ax m∗y+bm*y+bmy+b
a∗x−m∗y=ba*x-m*y=baxmy=b
y′=−yy'=- yy=y
根据裴蜀定理可知
a∗x+m∗y′=ba*x+m*y'=bax+my=b 当且仅当gcd(a,m)∣bgcd(a,m)|bgcd(a,m)b时有解
解为 x=x∗x=x*x=x bgcd(a,m)\frac{b}{gcd(a,m)}gcd(a,m)b modmodmod mmm

9.中国剩余定理(孙子定理)

9.1 定理说明

{x≡a1(mod m1)x≡a2(mod m2)⋅⋅⋅x≡an(mod mn) \begin{cases} x ≡ a_1 (mod\ m_1)\\ x ≡ a_2 (mod\ m_2)\\ ···\\ x ≡ a_n (mod\ m_n)\\ \end{cases} xa1(mod m1)xa2(mod m2)⋅⋅⋅xan(mod mn)

假定整数m1,m2⋅⋅⋅mnm_1,m_2···m_nm1,m2⋅⋅⋅mn两两互质,则对任意的整数:a1,a2⋅⋅⋅ana_1,a_2···a_na1,a2⋅⋅⋅an,方程组SSS有解。
方程的解为:
x=∑i=1nai∗ti∗Mix=\sum_{i=1}^{n} a_i*t_i*M_ix=i=1naitiMi
其中,
M=∏i=1nmiM=\prod_{i=1}^{n} m_iM=i=1nmi
Mi=MmiM_i=\frac{M}{m_i}Mi=miM
ti=mi−1(mod Mi)t_i=m_i^{-1} (mod\ M_i)ti=mi1(mod Mi)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值