同余方程(扩欧模板)

洛咕

题意:求关于x的同余方程\(ax\equiv1\pmod{b}\)的最小正整数解.

方程\(ax\equiv1\pmod{b}\)有解当且仅当\(gcd(a,b)=1\).所以方程可写为\(a*x+b*y=1\),用扩展欧几里得算法求出一组特解\(x_0,y_0\),通解是所有模b与\(x_0\)同余的整数,题目要求最小的解,故答案就是\((x_0+b)\mod b\).

#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline LL read(){
   LL s=0,w=1;char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
   return s*w;
}
LL exgcd(int a,int b,LL &x,LL &y){
    if(b==0){x=1;y=0;return a;}
    int d=exgcd(b,a%b,y,x);
    y-=x*(a/b);
    return d;
}
int main(){
    LL a=read(),b=read(),x,y;
    exgcd(a,b,x,y);
    printf("%lld\n",(x+b)%b);
    return 0;
}

原文地址:https://www.cnblogs.com/PPXppx/p/10500552.html

时间: 2024-08-30 18:33:26

同余方程(扩欧模板)的相关文章

P1082 同余方程(扩欧模板)

https://www.luogu.org/problem/P1082 #include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <cmath> #include <cstring> #define inf 2147483647 #define N 1000010 #define p(a) putchar(a) #defin

『扩欧简单运用』

扩展欧几里得算法 顾名思义,扩欧就是扩展欧几里得算法,那么我们先来简单地回顾一下这个经典数论算法. 对于形如\(ax+by=c\)的不定方程,扩展欧几里得算法可以在\(O(5log_{10}\min\{a,b\})\)的时间内找到该方程的一组特解,或辅助\(gcd\)判断该方程无解. 对于扩欧的详细讲解,可见『扩展欧几里得算法 Extended Euclid』. 那么我们注意到一个问题,扩展欧几里得算法求的只是一组特解.事实上,我们可以根据如下公式得到不定方程的通解: \[ \begin{cas

Codeforces Round #305 (Div. 2)C---Mike and Frog(扩欧+乱搞)

Mike has a frog and a flower. His frog is named Xaniar and his flower is named Abol. Initially(at time 0), height of Xaniar is h1 and height of Abol is h2. Each second, Mike waters Abol and Xaniar. So, if height of Xaniar is h1 and height of Abol is

扩展欧几里德算法.....哦,扩欧

首先推荐两篇比较好的博客 http://blog.csdn.net/lincifer/article/details/49391175 (然后下面便是一个蒟蒻的总结QAQ) 扩展欧几里德算法 基本算法: 对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 ax + by = gcd(a, b) = d. 证明: 设 a > b. 1. 显然当 b = 0,gcd (a,b) = a 时, x = 1,y = 0: 2. ab != 0

方程的解题解和扩欧的一些总结

题目描述 给出一个二元一次方程ax+by=c,其中x.y是未知数,求它的正整数解的数量. 输入输出格式 输入格式: 第一行一个整数T,表示有T组数据.接下来T行,每行3个整数a.b.c. 输出格式: 输出T行,每行一个数,表示方程解的数量.如果正整数解的数量比65535还多输出"ZenMeZheMeDuo". 题解 这个题一看就要先用扩展欧几里得求出一组x最小的整数解然后再计算出所有的解. 代码 1 #include<bits/stdc++.h> 2 using names

欧几里得(辗转相除gcd)、扩欧(exgcd)、中国剩余定理(crt)、扩展中国剩余定理(excrt)简要介绍

1.欧几里得算法(辗转相除法) 直接上gcd和lcm代码. 1 int gcd(int x,int y){ 2 return y==0?x:gcd(y,x%y); 3 } 1 int lcm(int x,int y){ 2 return x*y/gcd(x,y); 3 } 2.扩欧:exgcd:对于a,b,一定存在整数对(x,y)使ax+by=gcd(a,b)=d ,且a,b互质时,d=1. x,y可递归地求得. 我懒得改返回值类型了 1 long long exgcd(long long a,

poj 1061 同余方程+扩展欧几里得+(求最小非负整数解)

题目可以转化成求关于t的同余方程的最小非负数解: x+m*t≡y+n*t (mod L) 该方程又可以转化成: k*L+(n-m)*t=x-y 利用扩展欧几里得可以解决这个问题: eg:对于方程ax+by=c 设tm=gcd(a,b) 若c%tm!=0,则该方程无整数解. 否则,列出方程: a*x0+b*y0=tm 易用extend_gcd求出x0和y0 然后最终的解就是x=x0*(c/tm),y=y0*(c/tm) 注意:若是要求最小非负整数解? 例如求y的最小非负整数解, 令r=a/tm,则

P2485 [SDOI2011]计算器(快速幂+扩欧+bsgs)

题目描述 你被要求设计一个计算器完成以下三项任务: 1.给定y.z.p,计算y^z mod p 的值: 2.给定y.z.p,计算满足xy ≡z(mod p)的最小非负整数x: 3.给定y.z.p,计算满足y^x ≡z(mod p)的最小非负整数x. 为了拿到奖品,全力以赴吧! 输入输出格式 输入格式: 输入文件calc.in 包含多组数据. 第一行包含两个正整数T.K,分别表示数据组数和询问类型(对于一个测试点内的所有数 据,询问类型相同). 以下T 行每行包含三个正整数y.z.p,描述一个询问

欧几里得算法和扩欧

7.31.2018修改 欧几里得算法 概念 在数学中,辗转相除法,又称欧几里得算法(英语:Euclidean algorithm),是求最大公约数的算法. 辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的差的最大公约数. 两个数的最大公约数通常写成GCD(a, b),或者简写成(a, b) (引自wikipidia) 实现 用伪代码描述 //gcd(x,y) //(x>=y>0) while x!=0&&y!=0 z=x x=x mod y y=z 最后非零