OI基础数论

本文介绍了数论中的核心概念,如素数定理、算术基本定理、整除理论、同余理论,以及欧拉函数、乘法逆元和中国剩余定理等,并给出了相关定理的定义、性质和常见算法实现。
摘要由CSDN通过智能技术生成

声明:本文主要目的是供自己学习使用,部分来自OIWiki及学哥学姐指导,非本人原创。

数论

纯纯是研究理论数学的烧脑分支呀!!

让我们看看bing给出的定义:

初等数论主要就是研究整数环的整除理论及同余理论。此外它也包括了连分数理论和少许不定方程的问题。本质上说,初等数论的研究手段局限在整除性质上。

初等数论中经典的结论包括算数基本定理、欧几里得的质数无限证明、中国剩余定理、欧拉定理(其特例是费马小定理)、二次互反律, 勾股方程的商高定理、佩尔方程的连分数求解法等等。

我学的数论

本次集训接触数论是在最后一天,主要学习了如下内容:

1.素数定理

2.算数基本定理

3.整除理论

4.同余理论

5.乘法逆元

6.CRT

7.gcd,lcm,exgcd

8.exCRT

9.欧拉函数

10.莫比乌斯函数

11.Lucas定理

我只想记录已经完全学会的,所以本文持续更新(包括但不限于以上13类)

声明:以上的11个内容按照OI集训PPT顺序总结在下

一.素数定理

定义:素数,就是质数,它满足的性质是,只有1和它本身为它的公约数,也就是形如2,3,5……这样的数,规定:1不是素数,为什么呢?

1为什么不是素数:让我们看看一个叫整数分解定理的理论,请别问我为什么会学它。

对于任何一个整数m,有且仅有一组素数对(p1……pn)和正整数对(a1……an),使得m=p1^a1*......pn^an成立。

明白了吧。

对于1而言,分割方式有无限种,所以1虽然在素数定义处似乎没有什么破绽,但是到了整数分解定理这里,就显而易见了。

所以素数定理的内容是什么呢?

(令 π(n) 为小于等于 n 的素数个数,有 π(n)=Θ(n/lnn))

很是容易理解,所以不多说了。

二.算术基本定理

感觉这个就是上文的整数分解定理,但是不知道为什么学长为我们讲解了两次??

放个公式表达一下吧:

推出,素数的判定了

介绍四种方法:(思想就不介绍了OI数学必备)

1.定义O(√n)

//定义
for(int i = 1;i <= sqrt(n);i ++)
{
	if(n % i == 0)
	p[n] = 0;
}
p[n] = 1;

2.埃氏筛

//埃氏筛
for(int i = 2;i <= n;i ++) 
p[i] = 1;
for(int i = 2;i <= n;i ++)
{
	if(p[i])
	for(int j = i * 2;j <= n;j += i)
	p[j] = 0;
}

O(nloglogn)

3.欧拉筛

//欧拉筛
for(int i = 2;i <= n;i ++)
{
	if(!vis[i])
	p[pn ++] = i;
	for(int j = 1;i * p[j] <= n;j ++)
	{
		vis[i * p[j]] = 1;
		if(i % p[j] == 0)
		break;
	}
}

O(n)

4.我的筛法

我似乎发现了一种很新的素数筛法-CSDN博客

三.整除理论

“人如其名”很理论化的东西,印象中除了gcd应该没有什么代码吧,所以直接搬运PPT

对于整数 a 和 b,若存在整数 q 使得 aq=b,那么称 a 为 b 的约数,b 是 a 的倍数。记作 a|b 。 a|b, b|c −> a|c

a|b, a|c −> a|s×b+t×c

a|b, b|a −>|a|=|b|

note:正负均可

———————————————————————————————————————————

设 a 和 b 是两个整数,如果 d | a 且 d | b,则称 d 是 a 与 b 的公因子

设 a 和 b 是两个不全为 0 的整数,称 a 与 b 的公因子中最大的为 a 与 b 的最大公因子, 或最大公约数,记作gcd(a,b) 或(a,b)

设 a 和 b 是两个非零整数,称 a 与 b 最小的正公倍数为 a 与 b 的最小公倍数,记作 lcm(a,b)或[a,b]

———————————————————————————————————————————gcd和lcm的性质

+

gcd代码

//gcd
int gcd(int x,int y)
{
	return y == 0 ? x : gcd(y,x % y);
}
//O(log(a + b))

四.同余理论

整数 a,b 满足 m|a-b ,那么称 a 和 b 在模 m 下同余,记作 a ≡b (mod m)

对于 a ≡b (mod m) ,若 d|m ,则 a ≡b (mod d)

对于 a ≡b (mod m) ,若 d|m,d|a,d|b ,则 a/d ≡b/d (mod m/d)

对于 a ≡b (mod m) ,有 gcd(a,m)=gcd(b,m)

对于质数 m_1 和 m_2 ,若 gcd(m_1,m_2)=1 ,则 {m_2x_1+m_1x_2 mod m_1m_2|x_1,x_2∈ ℤ}= {x mod m_1m_2|x∈ ℤ}

exgcd

//exgcd 
void exgcd(int a,int b,int &g,int &x,int &y)
{
	if(!b)
	x = 1;
	y = 0;
	g = a;
	else
	{
		exgcd(b,a % b,g,y,x);
		y -= x * (a / b);
	}
}
//O(log(a + b))

如何证明??没有超出个人能力范围,但是真的要打好多字,所以上图

推论

乘法逆元,费马小定理,威尔逊定理

费马小定理:若 p 是质数,则对于任意整数 a 有 a^p=a (mod p)

威尔逊定理:若 p 是质数,则有 (p−1)!=−1 (mod p)

代码如何实现??

//线性推逆元
inv[1] = 1;
for(int i = 2;i <= p;i ++)
inv[i] = (p - p / i) * inv[p % i] % p; 
//O(n)

CRT(中国剩余定理)※

内容:

引用学长原话:掌握思想即可,代码易于实现,所以就不给你们板子了。但是我理论是懂了,代码不会啊学长啊啊啊(悲)

在这里感谢OIWiki上的板子

//CRT
LL CRT(int k,LL* a,LL* r) 
{
  LL n = 1,ans = 0;
  for(int i = 1;i <= k;i ++) 
  n = n * r[i];
  for(int i = 1;i <= k;i ++) 
  {
    LL m = n / r[i],b,y;
    exgcd(m,r[i],b,y);  // b * m mod r[i] = 1
    ans = (ans + a[i] * m * b % n) % n;
  }
  return (ans % n + n) % n;
} 

证明:还在研究……

拓展CRT

 所谓“扩展CRT”“扩展中国剩余定理”,其实就是⽤exgcd⼀个个合并这些同余⽅程。

以合并两个同余⽅程  

x ≡ b1 (mod m1)  

x ≡ b2 (mod m2)

为例,

⽅程组有解的充要条件是(m1,m2)|(b1-b2), 此时x在模[m1, m2]意义下 有唯⼀解。 该⽅程组等价于 x = b1 + m1y1 x = b2 + m2y2 则b1 - b2 = m2y2 - m1y1,  

exgcd求出y1、y2,可求出x在模[m1, m2]意义下的 唯⼀解 x =(b1 + m1y1)% [m1, m2]。

//excrt
#include<bits/stdc++.h>
#define int long long
#define LD long double
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf=2e18+100;
const int maxn=1e5+10;
int a[maxn],b[maxn];
int n;
int mul(int a,int b,int p)
{
	int x=(LD)a*b/p;//#define LD long double
	return ((a*b-x*p)%p+p)%p;//#define int long long
}
int exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	int gcd=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return gcd;
}
int exc()
{
	int prea=a[1],preb=b[1];
	for(int i=2;i<=n;i++)
	{
		int x,y;
		int d=exgcd(preb,b[i],x,y);
		int t=b[i]/d;//如果 (a[i]-prea)%d!=0则无解 
		x*=(a[i]-prea)/d;
		x=(x%t+t)%t;
		int temp=preb/d*b[i];
		prea=(preb*x+prea)%temp;
		//prea=(mul(preb,x,temp)+prea)%temp;
		preb=temp;
		//prea=prea%preb;
	}
	return prea;
}
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>b[i]>>a[i];
	}
	cout<<exc()<<"\n";
}
//  __int128 
/*
#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf=2e18+100;
const int maxn=1e5+10;
int a[maxn],b[maxn];
int n;
void print(__int128 x)
{
    if (x>9) print(x/10);
    putchar('0'+x%10);
}
__int128 exgcd(__int128 a,__int128 b,__int128 &x,__int128 &y)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	__int128 gcd=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return gcd;
}
__int128 exc()
{
	__int128 prea=a[1];
	__int128 preb=b[1];
	for(int i=2;i<=n;i++)
	{
		__int128 x,y;
		__int128 d=exgcd(preb,b[i],x,y);
		__int128 t=b[i]/d;
		x*=(a[i]-prea)/d;
		x=(x%t+t)%t;
		__int128_t temp=preb/d*b[i];
		prea=((preb%temp*x)%temp+prea)%temp;
		preb=temp;
		prea=prea%preb;
	}
	return prea;
}
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>b[i]>>a[i];
	}
	print(exc());
}

*/
*/

欧拉函数

⼀个数x的欧拉函数φ(x)为⼩于x的正整数中与x互质的数的个数

特别地,φ(1) = 1。

性质

1.积性函数!

(什么是积性函数?) 积性函数:若对任意互质的两个数m和n有f(m*n)=f(m)*f(n),则 f(x)是积性函数。若对任意两个数(不要求互质)都有 f(m*n)=f(m)*f(n),则f(x)是完全积性函数。

2.对质数p, φ(p)=p-1。

3. ⼩于n的数中,与n互质的数之和为φ(n)*n/2 (n>1)。

4. n的所有因数的欧拉函数之和等于n

——————————

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值