【ACWing】877. 扩展欧几里得算法

题目地址:

https://www.acwing.com/problem/content/879/

给定 n n n对正整数 a i , b i a_i,b_i ai,bi,对每对数,求一组 x i , y i x_i,y_i xi,yi,使得下式成立: a i x i + b i y i = gcd ⁡ ( a i , b i ) a_ix_i+b_iy_i=\gcd(a_i,b_i) aixi+biyi=gcd(ai,bi)

数据范围:
1 ≤ n ≤ 1 0 5 1\le n\le 10^5 1n105
1 ≤ a i , b i ≤ 2 × 1 0 9 1\le a_i,b_i\le 2\times 10^9 1ai,bi2×109

也可以用辗转相除法做。当 b = 0 b=0 b=0的时候,显然 ( a , b ) = a (a,b)=a (a,b)=a,那么一组解就是 x = 1 , y = 0 x=1,y=0 x=1,y=0。否则的话,设 d = ( a , b ) d=(a,b) d=(a,b),我们递归求解对于数对 b , a m o d    b b, a\mod b b,amodb的一组解 x ′ , y ′ x',y' x,y,那么有 b x ′ + ( a m o d    b ) y ′ = d bx'+(a\mod b)y'=d bx+(amodb)y=d,所以 b x ′ + ( a − ⌊ a b ⌋ b ) y ′ = d a y ′ + ( x ′ − ⌊ a b ⌋ y ′ ) b = d bx'+(a- \lfloor\frac{a}{b}\rfloor b)y'=d\\ ay'+(x'-\lfloor\frac{a}{b}\rfloor y')b=d bx+(abab)y=day+(xbay)b=d所以原方程的一组解就是 x = y ′ , y = x ′ − ⌊ a b ⌋ y ′ x=y',y=x'-\lfloor\frac{a}{b}\rfloor y' x=y,y=xbay。在代码里,我们可以将 x ′ x' x y ′ y' y的地位互换,这样可以少一次赋值。代码如下:

#include <iostream>
using namespace std;

// x和y传引用,在执行完exgcd这个函数之后,x和y里就存了一组解
void exgcd(int a, int b, int& x, int& y) {
    
    
    if (!b) {
    
    
        x = 1, y = 0;
        return;
    }

	// 递归调用的时候,换一下x和y的位置,这样可以少一次赋值
	exgcd(b, a % b, y, x);
    y -= a / b * x;
}

int main() {
    
    
    int n;
    cin >> n;

    while (n--) {
    
    
        int a, b, x, y;
        cin >> a >> b;
        
        exgcd(a, b, x, y);

        printf("%d %d\n", x, y);
    }

    return 0;
}

每次查询时空复杂度 O ( log ⁡ min ⁡ { a , b } ) O(\log \min\{a, b\}) O(logmin{ a,b})

猜你喜欢

转载自blog.csdn.net/qq_46105170/article/details/113824039