【模板】二元一次不定方程 exgcd
posted on 2022-09-17 15:59:26 | under 模板 | source
code
LL mod(LL x,LL m){return(x%m+m)%m;}
LL exgcd(LL a,LL b,LL c,LL& x,LL& y){
if(!b) return x=c/a,y=0,a;
LL res=exgcd(b,a%b,c,y,x);
return y-=a/b*x,res;
}
LL solve(LL a,LL b,LL c){
LL x,y,d=exgcd(a,b,c,x,y);
return c%d==0?mod(x,b/d):-1;
}
template <class T>
tuple<T, T, T> exgcd(T a, T b, T c) {
if (!b) return {c / a, 0, a};
auto [x, y, d] = exgcd(b, a % b, c);
return {y, x - a / b * y, d};
}
template <class T>
T solveEquation(T a, T b, T c) { // get the vaild solution x of ax + by = c
auto [x, y, d] = exgcd(a, b, c);
auto mod = [](T x, T y) { return (x % y + y) % y; };
return c % d == 0 ? mod(x, b / d) : -1;
}
template <class T>
T getInv(T a, T p) {
return solveEquation(a, p, 1);
}
调用 solve(a,b,c)
能求得
solve(n,P,1)
。
但是,为什么这样写对呢?
exgcd
我们想求的是这样一个东西的一组解
回忆一下我们求
将原方程的
取模的定义:
我们貌似看到了一组新的解
发现还有递归边界,此时
LL exgcd(LL a,LL b,LL& x,LL& y){
if(!b) return x=1,y=0,a;
LL res=exgcd(b,a%b,y,x);
return y-=a/b*x,res;
}
exgcd :: Integral a => (a, a) -> (a, a)
exgcd (a, 0) = (1, 0)
exgcd (a, b) = let (x, y) = exgcd (b, a `mod` b) in (y, x - (a `div` b) * y)
继续
exgcd 可以求出形如
由裴蜀定理得,如果
否则,等式两边同时乘
考虑这么一个式子,它和原方程等价:
显然
所以
code-analysis
LL mod(LL x,LL m){return(x%m+m)%m;}
LL exgcd(LL a,LL b,LL c,LL& x,LL& y){
if(!b) return x=c/a,y=0,a;
//x=c/a,提前算好 x_1,这里 a 是 gcd
LL res=exgcd(b,a%b,c,y,x);
return y-=a/b*x,res;
}
LL solve(LL a,LL b,LL c){
LL x,y,d=exgcd(a,b,c,x,y);
return c%d==0?mod(x,b/d):-1;
//先判无解,如果有解就模
}
本文来自博客园,作者:caijianhong,转载请注明原文链接:https://www.cnblogs.com/caijianhong/p/template-exgcd.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!