数论

目录

第一章 勾股数组

本原勾股数组

本原勾股数组是一个三元组(a,b,c,),其中a,b,c没有公因数,且满足a2+b2=c2

勾股数组定理

每个本原勾股数组(a,b,c)其中(a为奇数,b为偶数)都可以从以下公式得出:a=st,b=(s2-t2)/2,c=(s2+t2)/2,其中s > > >t ≥ \geq 1。

定理一

a和b奇偶不同,且c为奇数。
证明:
假设a和b都是偶数,则c一定为偶数,于是a,b,c存在最小公因式2,不满足本原勾股数a,b,c没有公因式的条件,假设不成立。
假设a,b都为奇数,则c一定为偶数,于是设a=2x+1,b=2y+1,c=2z,∵a2+b2=c2 ⟹ \Longrightarrow 4x2+4x+1+4y2+4y+1=4z2 ⟹ \Longrightarrow 2x2+2x+2y2+2y+1=2z2,而奇数不可能等于偶数,假设不成立。
故a,b奇偶不同,且c一定为奇数。

定理二

a为奇数,b为偶数,则c+b和c-b都是完全平方数。
证明:
设正整数d为c+b,c-b的公因数,则d整除c-b和c+b,d也整除(c+b)+(c-b)=2c和(c+b)-(c-b)=2b,由于b,c互素,因此d等于1或2,但d整除
(c-b)(c+b)=a2,由于a为奇数,所以d不能等于2,因此d等于1,因此c+b和c-b无公因数,由于(c-b)(c+b)=a2,a2为平方数,且(c+b)与(c-b)互素,因此二者均为平方数。

推论

由定理二,不妨设c-b=t2,c+b=s2,则可以解出a=st,b= s 2 − t 2 2 \frac{s^{2}-t^{2}}{2} 2s2t2,c= s 2 + t 2 2 \frac{s^{2}+t^{2}}{2} 2s2+t2,其中s > > >t ≥ \geq 1。。
若优势题目给出a,可令t=1,s=a,则可直接推出b和c。

第二章 勾股数组与单位圆

由上一张勾股数组a2+b2=c2,两边同时除以c2,可得(a/c)2+(b/c)2=1,其形式上近似与单位圆的方程,x2+y2=1,据勾股数组定理,可以得出任何圆上的可行点都可以表示为x= 2 s t x 2 + t 2 \frac{2st}{x^{2}+t^{2}} x2+t22st,y= s 2 − t 2 s 2 + t 2 \frac{s^{2}-t^{2}}{s^{2}+t^{2}} s2+t2s2t2,令m=s/t,,由于x和y的实际含义被扩展到了实数域上,因此m的范围也就变成了
(-∞,∞),圆x2+y2=1上坐标是有理数的店都可以由公式
(x,y)= 1 − m 2 1 + m 2 \frac{1-m^{2}}{1+m^{2}} 1+m21m2, 2 m 1 + m 2 \frac{2m}{1+m^{2}} 1+m22m)表示,其中m为有理数((-1,0)除外,此为m趋于∞是的极限值)。

第三章 高次幂之和与费马大定理

费马大定理:n ≥ \ge 3时,方程xn+yn=zn没有正整数解。

第四章 整除性与最大公因式

假设m与n是整数,且m不等于0,m整除n是指n是m的倍数,即存在整数k是的n=mk,记作m|n。

欧几里得算法

通过递推求a与b的最大公因数,记为gcd(a,b)。

typedef long long ll;
ll gcd(ll a,ll b){
   
return b?gcd(b,a%b):a;
}

第五章 线性方程和最大公因数

裴蜀定理

对于a,b,存在x,y使得ax+by=gcd(a,b)。

扩展欧几里得

求解gcd的同时求解方程ax+by=gcd(a,b)的一个解( x 0 x_{0} x0 y 0 ) y_{0}) y0,复杂度O(log(b))。

ll exgcd(ll a,ll b,ll &x,ll &y){
   
if(b==0){
   
y=0;
x=1;
return a;
}
ll r=exgcd(b,a%b,x,y);
ll temp=y;
y=x-(a/b)*y;
x=temp;
return r;
}

线性方程定理

设a与b是非0的整数,ax+by=gcd(a,b),总有一个解( x 0 x_{0} x0 y 0 y_{0} y0)且这个解可以通过扩展欧几里得算法得到,且方程的每一个解就可以表示为( x 0 x_{0} x0+k b g c d ( a , b ) \frac{b}{gcd(a,b)} gcd(a,b)b y 0 y_{0} y0-k a g c d ( a , b ) \frac{a}{gcd(a,b)} gcd(a,b)a),其中k为任意整数。

第六章 因式分解与算术基本定理

算术基本定理(唯一分解定理)

每个整数n ≥ \ge 2可唯一分解成素数成积n= p 1 p_{1} p1 p 2 p_{2} p2 p r p_{r} pr。即整数n可以以某种方式分解成素数乘积,且仅有一种这样的分解。

质因数分解

朴素分解

复杂度O( n \sqrt{n} n )

map<ll,ll>prime_factor(ll n){
   
map<ll,ll>res;
for(ll i=2;i*i<=n;i++){
   
while(n%i==0){
   
++res[i];
n/=i;
}
}
if(n!=1)res[n]=1;
return res;
}

pollard_rho算法

传说中的随机算法,复杂度O( n 1 / 4 n^{1/4} n1/4),适用于n较大的情况,判断一个大整数是否为素数用Miller_rabin算法,求一个大整数的所有质因数用Pollard_rho算法。
poj1181:求一个整数是否是素数,如果不是,则输出它最小的质因数。

#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
int t;
ll n,prim[1000];
ll ans;
int tot;
ll mul_mod(ll a,ll b,ll c)
{
   
	ll t=0;
	a%=c;
	b%=c;
	while(b){
   
		if(b&1){
   
			t=(t+a)%c;
		}
		a<<=1;
		a%=c;
		b>>=1;
	}	
	return t;
}
//ll pow_mod(ll a,ll b,ll c)
//{
   
//	ll t=1;
//	while(b){
   
//		if(b&1) t=(t*a)%c;
//		b>>=1;
//		a=(a*a)%c;
//	}
//	return t;
//}
ll pow_mod(ll x,ll n,ll mod){
     
    if (n==1) return x%mod;
    int bit[90],k=0;
    while (n){
   
        bit[k++]=n&1;
        n>>=1;
    }
    ll ret=1;
    for (k=k-1;k>=0;k--){
   
        ret=mul_mod(ret,ret,mod);
        if (bit[k]==1) ret=mul_mod(ret,x,mod);
    }
    return ret;
}
bool check(ll a,ll n,ll x,ll t)
{
   
	ll ret=pow_mod(a,x,n);
	ll tmp=ret;
	for(int i=0;i<t;i++){
   
		ret=mul_mod(ret,ret,n);
		if(ret==1&&tmp!=1&&tmp!=n-1) return true;
		tmp=ret;
	}
	if(ret!=1) return true;
	return false;
}
bool Miller_rabin(ll n)
{
   
	ll x=n-1,t=0;
	while((x&1)==0){
   
		x>>=1;
		t++;
	}
	int ok=1;
	if(t>=1&&(x&1)){
   
		for(int i=0;i<20;i++){
   
			ll a=rand()%(n-1)+1;
			if(check(a,n,x,t)){
   
				ok=1;break;
			}
			ok=0;
		}
	}
	if(!ok||n==2) return false;
	return true;
}
//ll gcd(ll a,ll b)
//{
   
//	if(b==0) return a;
//	return gcd(b,a%b);
//}
ll gcd(ll a,ll b){
   
    if (a==0) return 1;
    if (a<0) return gcd(-a,b);
    while (b){
   
        ll t=a%b; a=b; b=t;
    }
    return a;
}
ll Pollard_rho(ll x,ll c)
{
   
	ll i=1,k=2;
	ll x0=rand()%x,y=x0;
	while(1){
   
		i++;
		x0=(mul_mod(x0,x0,x)+c)%x;
		ll d=gcd(y-x0,x);
		if(d>1&&d<x) return d;
		if(y==x0) return x;
		if(i==k){
   
			y=x0;
			k+=k;
		}
	}
}
void findfac(ll n)
{
   
	if(!Miller_rabin(n)){
   
		prim[tot++]=n;
		return;
	}
	ll p=n;
	while(p>=n) p=Pollard_rho(p,rand()%(n-1)+1);
	findfac(p);
	findfac(n/p);
}
int main()
{
   
	srand(time(NULL));
	scanf("%d",&t);
	while(t--){
   
		scanf("%lld",&n);
		if(!Miller_rabin(n)){
   
			printf("Prime\n");
			continue;
		}
		tot=0;
		findfac(n);
		ans=prim[0];
		for(int i=1;i<tot;i++){
   
			ans=min(ans,prim[i]);
		}
		printf("%lld\n",ans);
	}
}

第七章 同余式

如果m整除a-b,则称a-b模m同余,记为a ≡ \equiv b(mod m)
其中m记为同余式的模,具有相同模的同余式,在许多方面表现得像通常的等式,其满足同余式的加减乘法,如 a 1 ≡ b 1 a_{1}\equiv b_{1} a1b1(mod m)且 a 2 ≡ b 2 a_{2}\equiv b_{2} a2b2(mod m),
a 1 ± a 2 ≡ b 1 ± b 2 a_{1}\pm a_{2}\equiv b_{1}\pm b_{2} a1±a2b1±b2(mod m),且 a 1 a 2 ≡ b 1 b 2 a_{1}a_{2}\equiv b_{1}b_{2} a1a2b1b2(mod m)
但是同余式除法仅在除数与模数互素时成立,即ac ≡ \equiv bc(mod m)仅在gcd(c,m)=1时成立。

线性同余定理

求解同余式:设a,c与m均是整数,m ≥ \ge 1,并设g=gcd(a,m)
∙ \bullet 如果g ∤ \nmid c,则同余式ax ≡ \equiv c(mod m)无解;
∙ \bullet 如果g|c恰好有g个不同的解,要求这些解则先要求线性方程au+mv=g的一个解(通过扩展欧几里得算法)( u 0 u_{0} u0 v 0 v_{0} v0),则 x 0 x_{0} x0= c u 0 g \frac{cu_{0}}{g} gcu0是该同余式的一个解,
而解的完全集为x ≡ \equiv x 0 x_{0} x0+k ⋅ \cdot m g \frac{m}{g} gm(mod m) k=0,1,2,3,…,g-1。

模p多项式根定理

设p为素数,f(x)= a 0 a_{0} a0xd+ a 1 a_{1} a1xd-1…= a d a_{d} ad是次数为d ≥ \ge 1的整系数多项式,则p ∤ \nmid a 0 a_{0} a0,则同余式f(x)$\equiv$0(mod p)最多又d个模p不同余的解。

第八章 威尔逊定理

当且仅当p为素数时,p|(p-1)!+1。
其逆反命题为当p是合数,则(p-1)! ≢ \not\equiv -1(mod p)。

第九章 同余式、幂与费马小定理

费马小定理

设p为素数,a是任意整数,且a ≡ ̸ \equiv\not 0(mod p)(即p ∤ \nmid a),则有ap-1 ≡ \equiv 1(mod p)

第十章 同余式、幂与欧拉公式

欧拉公式

如果gcd(a,m)=1则
a φ ( m ) a^{\varphi(m)} aφ(m) ≡ \equiv 1(mod m),其中 φ ( m ) \varphi(m) φ(m)为欧拉函数,意指区间[1,m]之间与m互质的数的个数。

第十一章 乘法逆元

逆元的意义

对于一些题目会要求把结果模一个数,通常是一个较大的质数,对于加减乘法通过同余定理可以直接拆开计算,但对于(a/b)%mod这个式子,是不可以写成 a % m o d b % m o d % m o d \frac{a\%mod}{b\%mod}\%mod b%moda%mod%mod的,但是可以写成(a+b-1) % \% %mod,其中b-1表示b的逆元。

费马小定理求逆元

由费马小定理可知,当p为质数,且q ∤ \nmid a时有ap-1 ≡ \equiv 1(mod p)分解后就可以写成a ⋅ \cdot ap-2 ≡ \equiv 1(mod p),故可知当p为质数,a,p互质时a关于p的逆元就是ap-2,因此通过快速幂求解即可,复杂度O(log(mod))。
费马小定理求逆元模板

ll qkpow(ll a,ll b,ll mod){
   
ll t=1,tt=a%mod;
while(p){
   
if(p&1)t=t*tt%mod;
tt=tt*tt%mod;
p>>=1;
}
return t;
}
ll getinv(ll a,ll mod){
   
return qkpow(a,mod-2,mod);
}

欧拉公式求逆元

与费马小定理同理,当a,p互质,但p不一定为质数时,需要采用欧拉公式使得a-1 a φ ( p ) − 1 a^{\varphi(p)-1} aφ(p)1,在模板中将mod-2改为 φ ( m o d ) − 1 \varphi(mod)-1 φ(mod)1即可,时间复杂度O(log( φ \varphi φ(mod)))。

扩展欧几里得算法求逆元

当所给的数与模数不互素时,我们可以选择解线性方程的方式来解出一个数对应模数的逆元。
形如a ⋅ \cdot x ≡ \equiv 1(mod p)我们可以转化为ax+py=1,通过扩展欧几里得算法求出x即为对应p时的逆元,复杂度O(log(a))。
扩展欧几里得算法求逆元模板

ll exgcd(ll a,ll b,ll &x,ll &y){
   
if(b==0){
   
x=1,y=0;
return a;
}
ll ret==exgcd(b,a%b,y,x);
y-=a/b*x;
return ret;
} 
ll getinv(ll a,ll mod){
   
ll x,y;
ll d=exgcd(a,mod,x,y);
return d==1?(x%mod+mod)%mod:-1;
}

递推法求逆元

即打表求逆元,令模数为p,原数为i,令t=p/i,k=p%i,则有
t * i+k ≡ \equiv 0(mod p)
即-t * i ≡ \equiv k(mod p),当i为p的因数时,逆元不存在,不讨论,当i不是p的因数时自然有gcd(ik,p)=1,故可对原式做除法
-t ⋅ \cdot inv[k] ≡ \equiv inv[i](mod p)
将k,t重新代回,则有inv[i]=(p-p/i)*inv[p%i]%p
可在O(n)的时间内推出逆元。
递推法求逆元模板

ll inv[mod+5]
void getinv(ll mod){
   
inv[1]=1;
for(ll i=2;i<mod;i++)
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}

第十二章 欧拉函数与中国剩余定理

欧拉函数

φ(m)为欧拉函数,意指区间[1,m]之间与m互质的数的个数。
φ \varphi φ函数公式
{ φ ( p k ) = p k − p k − 1 p 为 素 数 , k ≥ 1 φ ( m n ) = φ ( m ) φ ( n ) ( g c d ( m , n ) = 1 ) \begin{cases}\varphi(p^{k})=p^{k}-p^{k-1} & p为素数,k\ge 1 \\ \varphi(mn)=\varphi(m)\varphi(n)&(gcd(m,n)=1)\end{cases} { φ(pk)=pkpk1φ(mn)=φ(m)φ(n)pk1(gcd(m,n)=1)

欧拉函数筛

#include<iostream>  
#include<cstdio>  
#define N 40000  
using namespace std;  
int n;  
int phi[N+10],prime[N+10],tot,ans;  
bool mark[N+10];  
void getphi()  
{
     
   int i,j;  
   phi[1]=1;  
   for(i=2;i<=N;i++)//相当于分解质因式的逆过程  
   {
     
       if(!mark[i])  
           {
     
             prime[++tot]=i;//筛素数的时候首先会判断i是否是素数。  
             phi[i]=i-1;//当 i 是素数时 phi[i]=i-1  
             }  
       for(j=1;j<=tot;j++)  
       {
     
          if(i*prime[j]>N)  break;  
          mark[i*prime[j]]=1;//确定i*prime[j]不是素数  
    
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值