一本通提高篇之同余问题(课堂笔记)

上课记的,有点乱

「一本通 6.4 例 1」青蛙的约会

式子推倒

x+mty+nt(modL)

mtntyx(modL)

(mn)tyx(modL)

t(yx)×(mn)1(modL)

逆元:若 x×x1(modL),则称 x1x 的逆元。

假设 (mn)=k,现在求 k1

拓展欧几里得

假设有 ax+by=1

gcd(a,b)=1,则有解,不然可以提一个 gcd(a,b) 出来。

r=amodb

bx+ry=1

这样子不断模下去,必然会出现 r=0,b=1,此时 x=y=1 即可。

现在我们假设知道:

ax+by=1

bx+ry=1

p=abr=aa=pb+r

带入得:

(pb+r)x+by=1

pbx+rx+by=1

b(px+y)+rx=1

此时我们发现这条式子与 bx+ry=1 很像,于是得到:

x=y

y=xpx

拓欧求逆元

axmodb+bymodb=1

axmodb=1

所以 xamodb 下的逆元。

code

void exgcd(int a, int b, int x, int y)
{
	if(b==0) x=y=1; 
	else
	{
		gcd(b, a%b, y, x); 
		y-=a/b*x; 
	}
}

int main()
{
	a=((m-n)%L+L)%L; //求a的逆元
	exgcd(a, L, x, y); 
}

题目解法

ax+by=c有解,ax+by 总是 gcd(a,b) 的倍数,所以 c 也要是 gcd(a,b) 的倍数。

#include<bits/stdc++.h>
using namespace std; 
#define int long long
int n, m, i, j, k; 
int x, y, p, q, L, a, b, c; 

void exgcd(int a, int b, int &x, int &y)
{
	if(b==0) x=c/a, y=0; 
	else
	{
		exgcd(b, a%b, y, x); 
		y-=a/b*x; 
	}
}//exgcd直接解方程

signed main()
{
	cin>>x>>y>>m>>n>>L;  
	a=((m-n)%L+L)%L;
	c=((y-x)%L+L)%L; 
	exgcd(a, L, p, q); 
	p=(p%L+L)%L; 
	if(a*p%L!=c) return printf("Impossible"), 0; 
	printf("%lld", p); 
	return 0; 
}
posted @   zhangtingxi  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示