前言:
全文均为蒟蒻作者手搓
虽也参考了许多 [luogu 题解/某SDN/cnblogs.com]
但很多地方均为作者瞎编
如有错误务必救救孩子
File
int GCD(int a,int b){
if(b==0)return a;
return GCD(b,a%b);
} Question 01 [贝祖定理]
根据 ax+by=GCD(a,b)
a,b均为正整数
求x,y的整数值。 Solution
因为ax+by=GCD(a,b)
并且GCD(a,b)=GCD(b,a%b)
所以ax+by=GCD(b,a%b)
由贝祖定理GCD(b,a%b)=bX+a%bY
我们求出x,y和下一层X,Y的关系扔到递归里求解即可
等量代换ax+by=bX+a%bY
又因为a%b=a-(a/b)*b (C++向下取整)
所以
ax+by=bX+[a-(a/b)*b]Y
=bX+aY-b*(a/b)*Y
=aY+b[X-(a/b)*Y]
所以得到
x=Y
y=X-(a/b)*Y
但是递归需要出口
当b=0时GCD(a,b)=a
即当b等于0时,ax+by=a
把b代入 ax+0y=a
显然此时x=1
y可以取任意整数
However
你能见到的 STD 都会把 y=0
为什么呢
因为 y= Rand()
不一定能满足上一层
GCD(a,b)=GCD(b,a%b)=b
而此时 a%b=0
代一下贝祖
ax+by=b
代入上一层
aY+b(X-a/b*Y)=b
显然 X=1,Y=0 仍然可以
但是 Y!=0 就不一定了
因为作者懒就统一写成 x=1,y=0 了
Code
//求解
//exGCD 函数的返回值是GCD(a,b)
//x,y 用引用的方式取回x,y的结果
int exGCD(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
return a;
}
//刚才得到的式子
int X,Y;
int GCD_answer=exGCD(b,a%b,X,Y);
x=Y;
y=X-(a/b)*Y;
return GCD_answer;
} 当然,该式子不是常见形式
我们可以直接把形参中的x,y传进去
用y记录Answer中“X”的值,x记录“Y”的值
此时
x=Y(correct)
y=X
显然y应该-=(a/b)*Y
而Y的值被x所记录
所以 y-=(a/b)*x Code Improved
int exGCD(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
return a;
}
int GCD_answer=exGCD(b,a%b,y,x);
y-=(a/b)*x;
return GCD_answer;
} Question 02 [线性同余方程]
根据 ax%m=b
a,b,m均为正整数
求 x
无解输出“Shit!” Solution
因为 ax%m=b
其等价于 ax=b+km
所以 ax-mk=b
定义 y=-k
所以 ax+my=b
而 Question 01 则是根据 ax+by=GCD(a,b) 求x,y的整数值。
这就要求 b=GCD(a,m)
但是显然有时b不等于GCD(a,b)却仍然有解 example a=3 m=5 b=3
GCD(a,m)=1
但 x=6 是不定方程的解 注意到若 b%GCD(a,b)==0
则 b=B*GCD(a,b) B为整数
ax+my=b 变为 ax+my=B*GCD(a,b)
已知求法的是 aX+mY=GCD(a,b)
显然
x=B*X
y=B*Y
是原方程的一组解 Code #include<bits/stdc++.h>
using namespace std;
int exGCD(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
return a;
}
int GCD_answer=exGCD(b,a%b,y,x);
y-=(a/b)*x;
return GCD_answer;
}
int main(){
int T,a,b,m,x,y,gcd_ans;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&a,&b,&m);
gcd_ans=exGCD(a,m,x,y);
if(b%gcd_ans==0){
printf("%d\n",(long long)x*b/gcd_ans%m);
}else{
puts("Shit!");
}
}
} Question 03 [逆元]
根据 ax%m=1
求 x (a 关于 m 的逆元)
要求 0<x<m
如没有输出“impossible” Solution
此题为 Question 02 弱化版
ax+my=1
要求 1%GCD(a,m)=0
即 GCD(a,m)=1
即 a,m 互质 Code #include<bits/stdc++.h>
#define int long long
using namespace std;
int exGCD(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
return a;
}
int GCD_answer=exGCD(b,a%b,y,x);
y-=(a/b)*x;
return GCD_answer;
}
signed main(){
int T,a,m,x,y;
scanf("%d",&T);
while(T--){
scanf("%d%d",&a,&m);
if(exGCD(a,m,x,y)==1){
printf("%d\n",(x%m+m)%m);
}else{
puts("impossible");
}
}
} Question 04 [P5656 exGCD]
给定不定方程 ax+by=c
1. 若该方程无整数解
输出 -1
2. 若该方程有整数解且有正整数解
输出其正整数解数量、所有正整数解中 x 的最小值、y 的最小值、x 的最大值、y 的最大值
3. 若方程有整数解但没有正整数解
输出所有整数解中 x 的最小正整数值、 y 的最小正整数值 Answer
Question 01 主体 + Question 02 思路
我们已经会求 ax+by=GCD(a,b)
根据 Question 02 可知
只要 c|GCD(a,b) 即可
否则无解
第一条解决 现在假设我们已经求出一组解 x,y 使 ax+by=GCD(a,b)
目标是求出所有解 X,Y ,使 aX+bY=c //注意这里!
我们简写 GCD(a,b) 为 gcd,设c=base*gcd
ax+by=gcd
a*(x*base)+b*(y*base)=c
得到
{X=x*base
{Y=y*base
为原方程的一组解 接下来我们从一组解推所有的解
设 a(X+m)+b(Y+n)=c
展开得 (aX+bY)+(am+bn)=c
代入 c+(am+bn)=c
所以 am+bn=0 简单思考可能会得到
{m=kb
{n=-ka
但其实它不对(会有遗漏)
我们就想凑出一个数使其有 a,b 两个约数
而最小的,额...
应该是LCM(a,b)//不是LCA啊喂
众所周知
LCM(a,b)=a*b/GCD(a,b)
所以
m 和 n 应都除上 gcd fixed
{m=kb/gcd
{n=-ka/gcd 所以使劲带入一下
{X=x*base+kb/gcd
{Y=y*base-ka/gcd
(k 是正整数)
可以看出当 k 增大的时候 X 越来越大 Y 越来越小 接下来我们试着求一下 X(min)//正整数解
由题需要 k 尽量小
因为要求其是正整数
所以 x*base+kb/gcd>=1
所以 kb/gcd>=1-x*base
所以
1-x*base
k>= ----------- (double)
b/gcd but!
double 显然不甚理想
所以将其上取整
example
k>=4.5
k 必然是 5 而非 4 所以
X(min)=x*base+(1-x*base+b/gcd-1)/(b/gcd)*b/gcd//上取整 so 别化简了
=x*base+(b/gcd-x*base)/(b/gcd)*b/gcd
//这个结果是作者自己推导的
//有问题欢迎指出
//一定诚挚感谢并%神犇好人
根据奇妙的原理
此时 Y 取 max
aX(min)+bY(max)=c
Y(max)=(c-aX(min))/b 此时如果 Y(max)<0 那么没有正整数解 求个 Y(min)
需要 k 尽量大
y*base-kb/gcd>=1
所以 -kb/gcd>=1-y*base
所以
y*base-1
k<= -----------
b/gcd
这个就是下取整了
Y(min)=y*base+(y*base-1)/(b/gcd)*b/gcd
X(max)=(c-b*Y(min))/a; luogu 网友温馨提示我:
十年 OI 一场空,不开 long long 见祖宗!
孩子...虽然我不在了...但你要拾起我的旗帜...并打开快读... So...QED...了吗 Code 后记:
写到此处我很想写一些文采斐然的语句表示我强烈的情感
但想到管理还要看
唉...
还是算了

exGCD 2025/1/10的更多相关文章

  1. .NET周报【10月第3期 2022-10-25】

    国内文章 聊一聊被 .NET程序员 遗忘的 COM 组件 https://www.cnblogs.com/huangxincheng/p/16799234.html 将Windows编程中经典的COM ...

  2. Codeforces Round #175 (Div. 2) A~D 题解

    A.Slightly Decreasing Permutations Permutation p is an ordered set of integers p1,  p2,  ...,  pn, c ...

  3. 使用Excel制作万年历(可打印)

    先来看看A4纸打印效果,其他功能后续继续完善中. 年份数据字典(农历节日) 农历节日表 年度 春节 元宵节 龙抬头 端午节 六月六 七月七 七月十五 仲秋节 除夕 2010年02月14日 2010年0 ...

  4. 软件测试_Linux

    # Linux## 基础知识### 操作系统* 作为中间人,连接软件和硬件### Linux * 特点 * 免费+安全### 查看日志,定位bug,修改文件,搭建环境## 安装### 装虚拟机 vmw ...

  5. Windows10 版本说明 From wiki 20190104

    Windows版本说明 文字版本的: PC版本历史[编辑] 索引:       旧版本       旧版本,受支援       最新版本       最新预览版本 Version 1507(Windo ...

  6. 使用Excel制作万年历(日历可A4纸打印)

    先来看看A4纸打印效果,其他功能后续继续完善中. 年份数据字典(农历节日) 农历节日表 年度 春节 元宵节 龙抬头 端午节 六月六 七月七 七月十五 仲秋节 除夕 2010年02月14日 2010年0 ...

  7. MATLAB之数学建模:深圳市生活垃圾处理社会总成本分析

    MATLAB之数学建模:深圳市生活垃圾处理社会总成本分析 注:MATLAB版本--2016a,作图分析部分见<MATLAB之折线图.柱状图.饼图以及常用绘图技巧> 一.现状模式下的模型 % ...

  8. 夯实Java基础(十四)——Java8新的日期处理类

    1.前言 Java8之前处理日期一直是Java程序员比较头疼的问题,从Java 8之后,Java里面添加了许多的新特性,其中一个最常见也是最实用的便是日期处理的类——LocalDate.LocalDa ...

  9. 脑桥Brain-Pons

    date: 2014-02-01 15:30:11 updated: 2014-02-01 15:30:11 [一] "2025.7.3.Brain-Pons?Expeiment?Under ...

  10. 201871030102-崔红梅 实验二 个人项目—— D{0-1}KP 项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 实验二作业链接 我的课程学习目标 1.熟练掌握将本地代码保存至GitHub中2.掌握折扣背包问题3.回顾动态规划算法和回溯算法4.对java语 ...

随机推荐

  1. WebSocket详解:技术原理、代码演示和应用案例

    1.内容简介 本文将简要介绍 WebSocket 的由来.原理机制以及服务端/客户端实现,并以实际客户案例指导并讲解了如何使用 WebSocket 解决实时响应及服务端消息推送方面的问题.本文适用于熟 ...

  2. ctfshow--web7 sql注入空格过滤

    ?id=10//union//select//1,database(),3//%23查看库名 查看表名 -1/**/union/**/select/**/1,(select/**/group_conc ...

  3. 关于galaxy戒色的通知

    明天开始--一小段时间内辅以半退网 如果想打胶 就做100个卷腹 睡不着就吃褪黑素 恁还是多写写诗吧,恁现在这个精虫上脑的脑子连意识流都扛不住 恁还想写<阑山><莲天>< ...

  4. Frp内网穿透(一)

    ftp简介 frp frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https协议. 利用处于内网或防火墙后的机器,对外网环境提供 http 或 https ...

  5. Flume概念和启动过程分析

    一.概念 flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的系统. Flume系统中核心的角色是agent,agent本身是一个Java进程,一般运行在日志收集节点. 一个agent内 ...

  6. log4net 配置数据库连接

    http://logging.apache.org/log4net/release/config-examples.html MS SQL Server The database table defi ...

  7. Java中List通过Lambda实现排序

    目录 1.正常排序,1,2,3 2.倒序 3,2,1 1.正常排序,1,2,3 list=list.stream().sorted(Comparator.comparing(VipCardVo::ge ...

  8. springboot+vue项目:工具箱

    常用账号管理:工作相关账号.游戏账号.各平台账号 加班调休管理:公司没有对应的系统,需要自己记录加班调休情况. 待办事项:方便记录待办,以提醒还有哪些事情没有办理. 待实现功能: 1.点击侧边栏菜单, ...

  9. CPrimerPlus

    还没学 的 167页的wordcnt程序 199页的checking程序(太长了,不想看) 113页的第八章编程练习5(不想看) 125页的复习题9(有问题,有时间再来验证) 119页重定向和文件(n ...

  10. Python文档字符串设置--在PyCharm中

    引言 在PyCharm中,只要我们在一个函数下面输入一个三引号"""并回车,PyCharm会自动帮我们补全文档字符串,如下图所示: 然而,有些小伙伴的pycharm却无法 ...