例题:​​NOIP2012同余方程​​​ 题目要求关于扩展欧几里得的理解与应用_数论的同余方程扩展欧几里得的理解与应用_数论_02的最小正整数解

题目中的扩展欧几里得的理解与应用_数论_02等价于扩展欧几里得的理解与应用_辗转相除法_04
只不过这里的扩展欧几里得的理解与应用_扩展欧几里得_05一般为负数
根据裴蜀定理,扩展欧几里得的理解与应用_exgcd_06有整数解的充要条件是扩展欧几里得的理解与应用_exgcd_07
这里的扩展欧几里得的理解与应用_同余方程_08扩展欧几里得的理解与应用_数论_09,所以扩展欧几里得的理解与应用_扩展欧几里得_10也只能为扩展欧几里得的理解与应用_数论_09,即扩展欧几里得的理解与应用_同余方程_12互质
扩展欧几里得求的东西是扩展欧几里得的理解与应用_exgcd_13的整数解
所以放到这里正好适用,因为扩展欧几里得的理解与应用_扩展欧几里得_10就是扩展欧几里得的理解与应用_数论_09
由辗转相除法可知扩展欧几里得的理解与应用_扩展欧几里得_16
假设我们现在有一组解扩展欧几里得的理解与应用_数论_17满足扩展欧几里得的理解与应用_exgcd_18
由模法的定义可知扩展欧几里得的理解与应用_exgcd_19
所以上式可以化为扩展欧几里得的理解与应用_同余方程_20
所以扩展欧几里得的理解与应用_同余方程_21扩展欧几里得的理解与应用_exgcd_22
这里的扩展欧几里得的理解与应用_辗转相除法_23还需要一个扩展欧几里得的理解与应用_exgcd_24来求得
这样一直递归下去,扩展欧几里得的理解与应用_扩展欧几里得_25变成扩展欧几里得的理解与应用_数论_26扩展欧几里得的理解与应用_数论_26变成扩展欧几里得的理解与应用_数论_28
扩展欧几里得的理解与应用_数论_26总会为扩展欧几里得的理解与应用_辗转相除法_30扩展欧几里得的理解与应用_数论_26扩展欧几里得的理解与应用_辗转相除法_30时,扩展欧几里得的理解与应用_exgcd_13就可以写成扩展欧几里得的理解与应用_exgcd_34
很明显这里的扩展欧几里得的理解与应用_数论_35,需要回溯进上一层递归,扩展欧几里得的理解与应用_扩展欧几里得_05取任意值都可,一般回溯扩展欧几里得的理解与应用_辗转相除法_30

NOIP2012同余方程代码,这里的exgcd是简化之后的:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
void exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {x = 1; y = 0; return;}
exgcd(b, a % b, y, x); y -= (a / b) * x;
}

int main(int argc, char const *argv[]) {
ll a, b, x, y; cin >> a >> b;
exgcd(a, b, x, y); cout << (x + b) % b << endl;
}