首页 > 其他分享 >数论-同余与扩展欧几里得详解(附例题及代码)

数论-同余与扩展欧几里得详解(附例题及代码)

时间:2023-08-21 17:33:04浏览次数:40  
标签:gcd int 逆元 long 同余 详解 例题 mod

数论-同余与扩展欧几里得详解(附例题及代码)

注意:这篇文章的信息量会有一点多,请耐心看完

一.同余

1.1 同余的定义

给定一个正整数m,如果两个整数a和b满足a-b能够被m整除,即(a-b)/m得到一个整数,那么就称整数a与b对模m同余,记作a≡b(mod m)

简单来说,对于x,y,若x%p=y%p,即x,y对于p的余数相同,则称为同余

1.2 同余的性质

本身不重要,但我们可恶的教练让我们背下来

于是摆烂…………………………

实在是不想码出来()

二.求解乘法逆元

2.1费马小定理(很费马)

2.1.1费马小定理简介

假设a是一个整数,p是一个质数,则有以下定理

\(a^{p-1}\)≡1(mod p)

证明方法:出门左转,百度点击有惊喜)欢迎您

2.1.2费马小定理求解逆元

p为质数,则有\(a^{p-1}\)≡1(mod p)

则不难推出:\(a^{p-2}\)*a≡1(mod p)

所以,\(a^{p-2}\)就是a再在%p意义下的逆元

2.2欧拉定理

2.2.1欧拉定理简介

\(a^{φ(p)}\)≡1(mod p)(即为费马小定理的一般形式)

φ(p)为欧拉函数,不清楚的请出门左转见百度

2.2.2费马小定理求解逆元

推理:\(a^{φ(p)-1}\)*a≡1(mod p)

所以\(a^{φ(p)-1}\)就是a在%p意义下的逆元

2.2.3代码实现

  long long ksm(long a,long p,long long mod){//快速幂 
	long long t=1,x=a%mod;
	while(p){
		if(p&1) t=t*x%mod;
		x=x*x%mod;
		p>>1;
	}
	return t;
  }
  long long getinv(long long a,long long mod){//inv一般表示逆元 
	return ksm(a,mod-2,mod); 
  }

2.3递推求解逆元(相信你十分了解递推)

2.3.1推理过程

p为模数,a为待求逆元(先设出来),所以\(a^{-1}\)是a在模p意义下的逆元

p=k*a+r(k为常数,r为p/a的余数->r<a(易得))

则k=[p/a],r=p%a

k*a+r≡0 (mod p)

此时,两边同除ar,得

k*\(r^{-1}\)+\(a^{-1}\)≡0(mod p)

\(a^{-1}\)≡-k*\(r^{-1}\)(mod p)

inv(a)≡-[p/a]*inv(p%a) (mod p)

以inv(1)==1 作为边界,开始递推

2.3.2代码实现

  void getinv(long long mod){
	inv[1]=1;//边界条件
	for(int i=2;i<mod;i++){
		inv[i]=(mod-mod/i)*inv[mod%i]%mod;//递推核心代码
	}
  }

2.4扩展欧几里得算法求逆元

2.4.1 前置知识-裴蜀定理(贝祖定理)

说明了对任何整数a、b和它们的最大公约数d

关于未知数x和y的线性不定方程(称为裴蜀等式):若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数

特别地,一定存在整数x,y,使ax+by=d成立

它的一个重要推论是:a,b互质的充分必要条件是存在整数x,y使ax+by=1.

由此,我们便可对式子进行化简

将同余式ax≡c(mod b)转化为ax+by=c(很重要,做题列方程化简几乎必定会用到,牢记)

2.4.2小知识-充要条件

充分必要条件也即充要条件,意思是说,如果能从命题p推出命题q,而且也能从命题q推出命题p ,则称p是q的充分必要条件,且q也是p的充分必要条件。

样例:

1 A=“三角形的三条边都相等”;B=“三角形的三个角都相等”。

A是B的充分必要条件;

2 A=“某人触犯了法律”;B=“应当依照刑法对他处以刑罚”。

A是B的必要不充分条件;(A触犯法律包含各种法,有刑法有民法;B已经确定是刑法。B属于A所以A是B的必要不充分条件)

3 A=“付了足够的钱”;B=“买到商店里的东西”。

A是B的必要不充分条件;( A付够了钱 可以买的是车、房子等;但是B能买到商店里的东西一定是要付够钱)

2.4.3扩展欧几里德算法—求最小整数解推导

ax1+by1=gcd(a,b)
   
ax2+by2=gcd(a,b)

可由此推出

ax1+by1=ax2+by2

a(x1-x2)=b(y2-y1)

因为gcd(a,b)为a,b的最大公因数,所以将 A=a/gcd(a,b),B=b/gcd(a,b),向下推出

A(x1-x2)=B(y2-y1)

此时A,B互质,继续向下推出

A(nB)=B(nA)

(x1-x2)=n*B

(y2-y1)=n*A

重点部分

这里从x入手,得

(x1-x2)=n*B

x1=x2+n*B

由此,我们推出了x解的通解公式 x=x0+n*B

同理,我们推出了y解的通解公式 y=y0-m*A

如果要求x的最小整数解,即x0,就为x0=x%B

如果我们要求的是 ax+by=c,还得先转化 x=x*c/gcd(a,b).

然后套入公式

B=b/gcd(a,b)

x0=x%(b/gcd(a,b))

证毕(博主已累成狗,点个推荐呗) 若还不清楚,可移步Ta的博客(讲的蛮详细的)

2.4.4扩展欧几里德算法—代码实现

  int exgcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1,y=1;
		return a;
	}
	int gcd=exgcd(b,a%b,y,x);//没错,这玩意能求gcd
    //不过c++是有系统函数求GCD的->__gcd(a,b);
	y-=a/b*x;
	return gcd;
  }

2.4.4扩展欧几里德算法—应用场景

(1).求解不定方程

(2).求解线性不定方程(线性同余方程)

(3).求解模的逆元

2.4.5扩展欧几里德算法—逆元求解

  int exgcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1,y=1;
		return a;
	}
	int gcd=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return gcd;
  }
  int getinv(int a,int p){
	int x,y,gcd;
	gcd=exgcd(a,p,x,y);
	if(gcd==1){
		x=(x%p+p)%p;
		return x;
	}else{
		cout<<"a,p不互质"<<endl;
		return 0; 
	}
  }

三.例题

3.1「NOIP2012」同余方程

思路:使用欧几里德扩展进行求解->模板题

代码如下

  #include<bits/stdc++.h>
  #define int long long
  using namespace std;
  int x=0,y=0;
  int exgcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}
	int g=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return g;
  }
  signed main(){
	int a,b;
	cin>>a>>b;
	exgcd(a,b,x,y);
	cout<<(x%b+b)%b;
	return 0;
  }

后续还会有数论的题解更新,敬请期待

标签:gcd,int,逆元,long,同余,详解,例题,mod
From: https://www.cnblogs.com/ldyzzz/p/17646636.html

相关文章

  • vulnstack1 红日靶场渗透详解
    目录环境搭建信息收集PhpMyAdmin后台GetshellintooutfileMysql日志文件写入shellCS后渗透MSF后渗透知识补充nmap参数分类参数速查表dirsearch环境搭建ip段设置kali(coleak):192.168.145.139Windows7(stu1):192.168.10.181、192.168.145.140Winserver2008(owa):192.168.1......
  • 逻辑清晰,详解社交源码Android开发SDK
    前篇我们讲解了有关如何在IOS平台开发集成SDK,那么今天来给大家简单讲解下如何在社交源码Android客户端上开发集成。1.获取SDK:从提供SDK的第三方开发者或公司获得SDK的相关文件和文档。2.导入SDK文件:将SDK的库文件(.jar或.aar格式)拷贝到Android项目的libs文件夹中。3.配置权限:检查并......
  • Linux init详解 (0,1,2,3,4,5,6)
    #0-停机(千万不能把initdefault设置为0)#1-单用户模式#2-多用户,没有NFS#3-完全多用户模式(标准的运行级)#4-没有用到#5-X11(xwindow)#6-重新启动(千万不要把initdefault设置为6)......
  • StoneDB 源码解读系列|Tianmu 引擎工具类模块源码详解(一)
    StoneDB源码解读系列文章正式开启,预计以周更的形式跟大家见面,请多多支持~本篇源码解读内容已进行直播分享,可在视频号观看直播回放,也可点击阅读原文跳转至B站观看回放视频。PPT内容可在社区论坛中查看下载:https://forum.stonedb.io/t/topic/89各个工具类属于Tianmu引擎......
  • FlashAttention算法详解
    这篇文章的目的是详细的解释FlashAttention,为什么要解释FlashAttention呢?因为FlashAttention是一种重新排序注意力计算的算法,它无需任何近似即可加速注意力计算并减少内存占用。所以作为目前LLM的模型加速它是一个非常好的解决方案,本文介绍经典的V1版本,最新的V2做了其他优化我们......
  • 06-中断详解
    目录一.中断原理二.NVIC详解一.中断原理1.中断过程和术语2.中断优先级概念3.中断优先级的表述方法4.中断源类型5.中断源的4种状态二.NVIC详解1.NVIC概念2.中断协作模型......
  • HTML5原生拖拽/拖放 Drag & Drop 详解
    前言拖放(drap&drop)在我们平时的工作中,经常遇到。它表示:抓取对象以后拖放到另一个位置。目前,它是HTML5标准的一部分。我从几个方面学习并实践这个功能。拖放的流程对应的事件我们先看下拖放的流程:选中--->拖动--->释放然后,我们一步步看下这个过程中,会发生的事情。选......
  • 【愚公系列】2023年08月 WPF控件专题 CheckBox控件详解
    (文章目录)前言WPF控件是WindowsPresentationFoundation(WPF)中的基本用户界面元素。它们是可视化对象,可以用来创建各种用户界面。WPF控件可以分为两类:原生控件和自定义控件。原生控件是由Microsoft提供的内置控件,如Button、TextBox、Label、ComboBox等。这些控件都是WPF中常见......
  • Arthas定位分析详解
    一、Arthas使用场景主要的场景如下:1、是否需要一个全局视角来查看系统的运行状况?2、系统CPU升高了,到底是哪里占用了CPU?3、运行的多线程有死锁吗?有阻塞吗?4、有什么方法可以监控到JVM的实时运行状态?二、Arthas安装使用可以在官方Github上进行下载,也可以在国内的码云Gitee......
  • C语言转义字符详解
    定义是以\开头的字符序列常用作用\n 换行\r  回到本行开头继续输出内容(原内容会被覆盖)\b 使光标左移一个位置\t  相当于四个空格\v 换到下一行继续输出\'  输出‘\" 输出“\ddd1~3位八进制数字,会自动转换成十进制的ascll码的对应字符\xhh 1~2......