扩展欧几里得算法如何应用于求解?

摘要:66.Acwing基础课第877题-简单-扩展欧几里得算法 题目描述 (给定 n 对正整数 a_i,b_i,对于每对数,求出一组 x_i,y_i,使其满足 a_i×x_i+b_i&amp
66.Acwing基础课第877题-简单-扩展欧几里得算法 题目描述 \(给定 n 对正整数 a_i,b_i,对于每对数,求出一组 x_i,y_i,使其满足 a_i×x_i+b_i×y_i=gcd(a_i,b_i)\)。 输入格式 \(第一行包含整数 n\)。 \(接下来 n 行,每行包含三个整数 a_i,p_i\)。 输出格式 \(输出共 n 行,对于每组 a_i,b_i,求出一组满足条件的 x_i,y_i,每组结果占一行\)。 \(本题答案不唯一,输出任意满足条件的 x_i,y_i 均可\)。 数据范围 \(1≤n≤10^5\), \(1≤a_i,b_i≤2×10^9\) 输入样例: 2 4 6 8 18 输出样例: -1 1 -2 1 代码: // 包含输入输出流头文件(cin/cout依赖,本代码用C风格IO,保留作为通用模板) #include <iostream> #include <algorithm> using namespace std; // 扩展欧几里得算法核心函数 // 功能:求解 ax + by = gcd(a, b) 的一组整数解 (x, y),并返回gcd(a, b) // 参数说明: // a, b:方程的系数 // x, y:引用传递,用于存储求得的一组解 // 返回值:d = gcd(a, b)(a和b的最大公约数) int exgcd(int a, int b, int &x, int &y) { // 递归边界:当b=0时,方程变为 a*1 + 0*0 = a,即gcd(a,0)=a if (!b) { x = 1, y = 0; // 此时特解为x=1,y=0 return a; // 返回最大公约数a } // 递归调用:欧几里得算法的核心(gcd(a,b)=gcd(b,a%b)) // 注意:递归时交换了x和y的位置,是为了后续推导方便 int d = exgcd(b, a % b, y, x); // 回溯推导解:从递归边界反向计算当前层的x,y // 推导依据: // 假设递归得到 b*x' + (a%b)*y' = d // 而 a%b = a - (a/b)*b(a/b是整数除法) // 代入得:b*x' + (a - (a/b)*b)*y' = d → a*y' + b*(x' - (a/b)*y') = d // 对比 ax + by = d,可得:x = y', y = x' - (a/b)*y' // 由于递归时已经交换了x和y(当前x是原来的y',当前y是原来的x') // 因此简化为:y -= a/b * x y -= a / b * x; return d; // 返回最大公约数 } int main() { int n; // n:测试用例的组数 // C风格输入:比cin更快,适合竞赛大数据量场景 scanf("%d", &n); // 循环处理n组测试用例 while (n -- ) { int a, b; // a, b:需要求解 ax + by = gcd(a,b) 的系数 scanf("%d%d", &a, &b); int x, y; // 存储方程的一组解 exgcd(a, b, x, y); // 调用扩展欧几里得算法求解 // 输出求得的一组特解x和y printf("%d %d\n", x, y); } return 0; // 程序正常结束 }