首页 > 其他分享 >数学及数学相关 学习笔记

数学及数学相关 学习笔记

时间:2023-11-27 22:45:41浏览次数:24  
标签:方程 gcd int 定理 笔记 学习 数学 ax mod

数学及数学相关

目录

  1. 前置知识与符号定义

  2. 快速幂

  3. 素数筛

  4. 裴蜀定理

  5. 扩展欧几里得算法(exgcd)

  6. 同余方程

  7. 费马小定理

  8. 模意义下的乘法逆元

  9. 欧拉定理

  10. 卢卡斯定理

  11. 中国剩余定理

0.前置知识与符号定义

0.0 缺省源

由于篇幅原因,下文的代码自动省略以下片段:

#include <bits/stdc++.h>
#define int long long 
using namespace std;

0.1. 素数

对于一个数 \(p\),\(p \ne 0,\pm 1\),且 \(p\) 没有除 \(1\) 与 \(p\) 以外的因数,则认为 \(p\) 是素数,否则认为 \(p\) 是合数。

0.2. 最大公因数

定义 \(\gcd(a,b)\) 为 \(a,b\) 两数的最大公因数,最大公因数是指同时是 \(a,b\) 的因数的数。

0.3. 整除符号

定义 \(d|a\) 表示 \(a\) 可被 \(d\) 整除。

0.4. 模运算

定义 \(a \mod b=a-\lfloor \frac{a}{b} \rfloor \times b\)。

特殊的,当输出一个数 \(k\) 对 \(p\) 取模的结果时,请使用 cout<<(k%p+p)%p 而非 cout<<k%p,这可能导致一些符号错误。

1. 快速幂

模板题

对于快速幂的问题定义如下:给定两个整数 \(a,b\),求 \(a^b \mod k\) 。

对于此类问题,暴力的时间复杂度是显然 \(O(n)\) 的,考虑优化。

我们不妨将指数采用二进制表述,设指数的二进制串为 \(S_{i}\),\(tmp\) 表示当前二进制位对答案的贡献,\(a\) 表示底数。

若 \(S_{k}=1\),则 \(ans \gets ans \times tmp\)。由于第 \(k\) 位对答案的贡献为\(a^{2^{k-1}} \times a^{2^{k-1}}\),即 \(a^{tmp} \times a^{tmp}\),化简得 \(a^{tmp^2}\) 所以我们在每次操作后使 \(tmp \gets tmp \times tmp\) 即可。

其时间复杂度为 \(O(\log n)\)。

代码:

int m;
int qpow(int a,int b)
{
	int ans=1,tmp=a;
	while(b!=0)
	{
		if(b&1)
		{
			ans=(ans%m*tmp%m)%m;
		}
		tmp=tmp*tmp%m;
		b>>=1;
	}
	return ans;
}

2. 素数筛

2.1. 埃氏筛

对于素数筛问题的模板题

埃氏筛的思想如下,若我们需要筛出小于等于 \(n\) 的素数,可以枚举 \(2\) 至 \(n\) ,若当前枚举的数 \(k\) 是一个素数,则我们将 \(k\) 的倍数都标志为合数。特殊的,我们不去关心小于 \(k\) 的 \(k\) 倍的数,因为该数在被 \(k\) 考虑之前一定被小于 \(k\) 的数考虑过。

可以证明,其时间复杂度为 \(O(n \log \log n)\)。

以下代码实现筛出 \(n\) 以内的质数:

void prime(int n)
{
	int t=0;
	for(int i=2;i<=n;i++)
		isprime[i]=1;
	for(int i=2;i<=n;i++)
	{
		if(isprime[i])
		{
			prime[++t]=i;
			if(i*i<=n)
				for(int j=i*i;j<=n;j+=i)
					isprime[j]=0;
		}
	}
}

2.2.欧拉筛

欧拉筛模板题

埃氏筛的时间复杂度为 \(O(n \log \log n)\),无法通过本题。

欧拉筛的时间复杂度为 \(O(n)\)。

对于欧拉筛,每一个数会且仅会被筛到一次。

其做法是对于一个数 \(k\),遍历当前质数表 \(S\)(\(S\) 呈单调递增),若 \(k \mod S_{i}=0\) 则停止遍历。

容易证明其正确性,若 \(k\mod S_{i}=0\),则说明 \(S_{i}\) 是 \(k\) 的最小质因数。即 \(S_{i+1}\) 一定不是其最小质因数。那么 \(i\) 乘上 \(S_{k+a}\) 的结果一定会被 \(S_{k}\) 的倍数筛到。

附代码:

void prime(int n)
{
	int t=0;
	for(int i=2;i<=n;i++)
	{
		if(!chck[i])
			pri[++t]=i;
		for(int j=1;i*pri[j]<=n&&j<=t;j++)
		{
			chck[i*pri[j]]=1;
			if(i%pri[j]==0)
				break;
			
		}
	}
}

3. 裴蜀定理

裴蜀定理的描述如下:

对于整数 \(a,b\)(\(a,b\) 中至少有一个不为 \(0\)),方程 \(ax+by=\gcd(a,b)\) 一定有解。

有以下推论:

  • 对于整数 \(a,b\)(\(a,b\) 中至少有一个不为 \(0\)),方程 \(ax+by=d\) ,则 \(d=\gcd(a,b)\)(逆定理)。

  • 对于一个数列 \(a\)(\(a\) 中元素不全为 \(0\)), \(\sum^{n}_{i=1} a_{i}x_{i}=\gcd^n_{i=1}a_{i}\) 一定有解。

该定理证明见 4.3。

4. 扩展欧几里得算法(exgcd)

4.1. 辗转相除法(欧几里得算法)

辗转相除法可以用来求解最大公因数等问题。

其主要算法流程如下:

  1. 给定两数 \(a,b\),我们认为 \(a>b\)。

  2. 若 \(b=0\) 返回 \(a\)。否则递归求解 \(\gcd(b,a \mod b)\)

算法正确性证明如下:

首先证明 \(\gcd(a,b)\) 的答案是 \(gcd(b,a \mod b)\) 的答案。

我们设 \(a=bk+c\),则 \(\gcd(a,a \mod b)=c\),设 \(d|a\) 且 \(d|b\) ,则有 \(c=a-bk\),\(\dfrac{c}{d}=\dfrac{a}{d}-\dfrac{b}{d}k\)。

不难发现 \(\dfrac{c}{d}\) 是整数,即 \(d|c\),所以 \(\gcd(a,b)\) 的答案是 \(gcd(b,a \mod b)\) 的答案。

逆命题容易证明。

Q.E.D

代码如下:

int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}

对于两整数 \(a,b\),有:

\[\gcd(a,b) \times \operatorname{lcm}(a,b) = a b \]

在此不做证明。

由此,有:

int lcm(int a,int b)
{
	return a*b/gcd(a,b);
}

请注意尽量不要使用 <cmath><algorithm> 库中的 __gcd() 函数,这可能导致被卡常。

请注意 <numeric> 库中的 std::gcdstd::lcm 仅在 C++ 17 及以上标准中可用,也就是说你在 CCF 的机子上用了就会喜提 CE 0 pts

4.2 扩展欧几里得算法

4.2.1. exgcd与裴蜀定理

扩展欧几里得算法(exgcd)常用于这样一类问题:给定一个不定方程 \(ax+by=c\),求其一组合法的整数解,即裴蜀定理。

即:求 \(ax+by=\gcd(a,b)\),并将求得的 \(x,y\) 分别乘以 \(\dfrac{c}{\gcd(a,b)}\)。

我们可以尝试将问题转化为 4.1 中的欧几里得算法问题,即为 exgcd 算法。

与欧几里得法相似的,我们可以将 \(ax+by=\gcd(a,b)\) 递归为 \(bx'+(a \mod b)y' = \gcd(b,a \mod b)\)

特殊的,exgcd 中 \(ax+by=\gcd(a,b)\) 与 \(bx'+(a \mod b)y' = \gcd(b,a \mod b)\) 并不等价。

由欧几里得算法:

\[bx'+(a \mod b)y' = \gcd(a,b)\iff bx'+(a \mod b)y' = \gcd(b,a \mod b) \]

假设 \(bx'+(a \mod b)y ' = \gcd(a,b)\) 中,\(x',y'\) 已知,由模运算定义:

\[ay'+b(x'-\lfloor\frac{a}{b}\rfloor y')=\gcd(a,b) \]

所以

\[x=y',y=x'-\lfloor\frac{a}{b}\rfloor y' \]

由定义,\(\gcd(a,0)=a\),此时 \(x=1,y=0\)。

所以我们只需要递归到 \(b=0\) 时终止即可。

于是我们求出了不定方程 \(ax+by=c\) 的一组整数解,这也间接地证明了裴蜀定理。

附代码:

int exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1,y=0;
		return a;
	}
	int h=exgcd(b,a%b,x,y);
	int xx=x,yy=y;
	x=yy,y=xx-a/b*yy;
	return h;
}

4.2.2. exgcd 求不定方程通解

假设我们已经知道了不定方程 \(ax+by=c\) 的一组解 \(x_{0},y_{0}\),若 \(x_{0}\) 增加 \(r\) 则方程左边增加 \(ar\),为保证等式成立,\(by\) 需减去 \(ar\),同时,\(y\) 是整数。这意味着 \(ar\) 是 \(b\) 的倍数。

我们不妨设 \(t=ar\),因为 \(ar\) 是 \(b\) 的倍数,所以最小的 \(t=\operatorname{lcm}(a,b)\)。

由最小公倍数性质:

\[\operatorname{lcm}(a,b)=ar=\dfrac{ab}{\gcd(a,b)} \]

带回原式,得:

\[r=\dfrac{b}{\gcd(a,b)} \]

所以,\(y\)需减去:

\[\dfrac{ar}{b}=\dfrac{\frac{ab}{\gcd(a,b)}}{b}=\dfrac{a}{\gcd(a,b)} \]

所以,不定方程 \(ax+by=c\) 的通解是:

\[x=x_{0}+\dfrac{b}{\gcd(a,b)}k,y=y_{0}-\dfrac{a}{\gcd(a,b)}k \]

4.2.3 不定方程的无解情况

这与裴蜀定理所讨论的情况不同

对于不定方程 \(ax+by=c\) 其有解的必要条件是 \(c \bmod \gcd(a,b) = 0\)

证明如下:由最大公因数定义,\(a,b\) 都是 \(\gcd(a,b)\) 的倍数,所以 \(ax+by\) 是 \(\gcd(a,b)\) 的倍数,即 \(c\) 是 \(\gcd(a,b)\) 的倍数。若 \(c \bmod \gcd(a,b) \ne 0\),与 \(c\) 是 \(\gcd(a,b)\) 的倍数矛盾,不成立。此时不定方程无解。

5. 同余方程

同余方程模板题

同余方程指的是形如 \(ax \equiv 1 \pmod b\) 的方程。

对于这种方程,我们可以将其转化为上文的不定方程 \(ax+by=c\)。

为什么?

\(a \equiv b \pmod p\) 的本质是 \(a\) 与 \(b\) 之间相差了若干个 \(p\)。

所以\(ax \equiv 1 \pmod b \iff ax+by \equiv 1\)

特殊的,与不定方程类似,同余方程同样可能无解,这发生在 \(a,p\) 不互质的情况,证明如下:

对于不定方程 \(ax+by=1\),其有解的条件是 \(1 \bmod \gcd(a,b)=0\),即 \(\gcd(a,b)\) 必须为 \(1\),即两数互质。

5.1. 同余方程的性质

咕咕咕

6. 费马小定理

费马小定理的描述如下:若 \(p\) 为素数,\(\gcd(a,p)=1\),则 \(a^{p-1}\equiv 1 \pmod p\)

费马小定理是欧拉定理的一个推论,将在下文证明其正确性。

7. 模意义下的乘法逆元

所以我们有必要先知道什么是模意义下的乘法逆元(本文不讨论其它逆元,下文逆元皆指“模意义下的乘法逆元”)。

给定二个整数 \(a, p\),若 \(ax \equiv 1\pmod p\),则称 \(x\) 是 \(a\) 的逆元。

7.1. exgcd求逆元

逆元模板题

显然可以用 5. 中提到的同余方程求解。

需要注意的是,由于不定方程可能无解,所以该种求逆元方式只适合 \(a,p\) 互质时。

值得注意的是,这里要求 \(a,p\) 互质,而费马小定理还要求 \(p\) 一定为质数

7.2. 费马小定理求逆元

由费马小定理,\(a^{p-1}\equiv 1 \pmod p\)。

而逆元要求的式子是 \(ax \equiv 1 \pmod p\)。

不难发现 \(x=a^{p-2}\),快速幂求出即可。

代码如下:

int pow(int a,int p)
{
	int poww=p-2;
	int pos=a,ans=1;
	while(poww)
	{
		if(poww&1)
			ans=ans*pos%p;
		pos=pos*pos%p;
		poww>>=1;
	}
	return ans;
}

时间复杂度 \(O(n\log n)\)

7.3. 线性求逆元

todo

8.欧拉定理

我们设 \(\phi(i)\) 为 \(1<=k<=i\) 中与 \(i\) 互质的数的个数。

欧拉定理如下:

\[a^{\phi(i)}\equiv 1 \pmod i \]

可以用一种构造的方式证明其正确性:


wrote on \(Nov.3^{rd},2023\)

标签:方程,gcd,int,定理,笔记,学习,数学,ax,mod
From: https://www.cnblogs.com/ChthollyNS/p/math-and-math-related.html

相关文章

  • 线性基学习笔记
    我废话怎么这么多wwwwwwwwwww\(\color{white}地址\)rebuild思想就是使满足线性基的条件下,使每一个二进制位只在一个位置上为1。可以用高斯消元直接处理出,也可以处理出任意一组线性基后从后往前扫一遍,如果\(a_i\)第\(j\)位上为\(1\),则\(a_i\oplusa_j\toa_i\)。此时如果......
  • spring事务学习
    1,spring方法内部调用亲自测试:同一个类中一个方法(无事务)调用另一个方法(有事务),事务不生效问题同一个类中一个方法(有事务)调用另一个方法(有事务),事务会生效   ......
  • Linux I/O重定向与管道的学习
    学习 Liunx 的 I/O 重定向与管道是理解 Liunx 系统的重要部分,以下是一些学习心得:1. 理解基本概念:在学习 I/O 重定向与管道之前,需要先理解 Liunx 的文件描述符、标准输入输出、文件系统等基本概念。- 文件描述符(File Descriptor):文件描述符是一个非负整数,用于标识打开......
  • 学习Python相关软件的安装
    学习Python相关软件的安装Typora软件的使用它不是国产软件的,它是国外的,官方网站是国外,在国内下载国外的软件,就会出现下载速度慢的问题#1.下载:https://typoraio.cn/这个软件不是免费使用的,虽然收费但是不贵,很好用!#2.这款软件是支持markdown格式的,是目前使用最为频繁......
  • 学习python的计算机基础
    编程与编程语言1.什么是语言? #语言就是人与人之间交流的媒介2.什么是编程语言呢? #就是人与计算机之间交流的媒介常见的编程语言:Python、Java、Go、PHP、C、C++、C#等3.什么是编程? #编程就是写代码编程就是程序员(码农)使用计算机能够读懂的语言把自己的'......
  • offline RL | BCQ:学习 offline dataset 的 π(a|s),直接使用 (s, π(s)) 作为 Q learni
    题目:Off-PolicyDeepReinforcementLearningwithoutExploration,ICLR2019pdf版本:https://arxiv.org/pdf/1812.02900.pdfhtml版本:https://ar5iv.labs.arxiv.org/html/1812.02900GitHub:https://github.com/sfujim/BCQ参考博客:https://zhuanlan.zhihu.com/p/493039753,......
  • 学习笔记12
    第十四章总结摘要MySQL关系数据库系统MySQL的重要性在Linux机器上安装和运行MySQL使用MySQL在命令模式和批处理模式下使用SQL脚本创建和管理数据库将MySQL与C编程相结合;演将MySQL与PHP集成,通过动态Web页面创建和管理数据库MySQL简介MySQL是一个关系数据库系统。在关系......
  • openGauss学习笔记-133 openGauss 数据库运维-例行维护-日维护检查项
    openGauss学习笔记-133openGauss数据库运维-例行维护-日维护检查项133.1检查openGauss状态通过openGauss提供的工具查询数据库和实例状态,确认数据库和实例都处于正常的运行状态,可以对外提供数据服务。检查实例状态gs_check-Uomm-iCheckClusterState检查参数openG......
  • java基础学习:三元运算符,运算符的优先级
    三元运算符介绍:格式:条件表达式?值1:值2;执行流程:首先计算关系表达式的值,如果值为true,返回值1,如果值为false,返回值2代码:packagecom.itheima.operator;publicclassOperator6{publicstaticvoidmain(String[]args){//目标:三元运算符的基本使用do......
  • 基于深度学习网络的烟雾检测算法matlab仿真
    1.算法运行效果图预览  2.算法运行软件版本matlab2022a 3.算法理论概述      基于深度学习网络的烟雾检测算法是一种端到端的检测方法,主要分为基于候选区域的二阶段目标检测器和基于回归的单阶段目标检测器两类。      基于候选区域的二阶段目标检测......