Tag Archives: 扩展欧几里德

[ACM] POJ1061解题报告

扩展欧几里德,ap+bq=c,此题中

a=m-n;
b=-l;
c=y-x;

递归到当b=0是停止此时p一定为1,q值不定,不妨设为0,再递归上去得到p0,然后通解是

p = p0 + b/Gcd(a, b) * t
q = q0 – a/Gcd(a, b) * t

此处有一个小问题 导致了我一直不能AC
设c是gcd的n倍,那么p0*=n,然而后面b/Gcd(a, b) * t要不要乘以n呢,答案是不要,没搞清楚为什么,反正不乘就过了..

1#include <cstdio>
2#include <cmath>
3    /*  p = p0 + b/Gcd(a, b) * t
4        q = q0 - a/Gcd(a, b) * t
5    45 165 63 22 10000          */
6 
7__int64 d;
8 
9void exgcd(__int64 *p,__int64 *q,__int64 a,__int64 b) {
10    __int64 x,y;
11    if(!b) {
12        *p=1;
13        *q=0;
14        d=a;
15        return;
16    }
17    exgcd(&x,&y,b,a%b);
18    *p=y;
19    *q=(x-a/b*y);
20    return;
21}
22 
23int main() {
24    __int64 x,y,m,n,l,a,b,c,p,q,t;
25    scanf("%I64d%I64d%I64d%I64d%I64d",&x,&y,&m,&n,&l);
26    a=m-n;
27    b=-l;
28    c=y-x;
29    exgcd(&p,&q,a,b);
30    if(c%d) {
31        printf("Impossible\n");
32        return 0;
33    }
34    n=c/d;
35    t=(b/d);
36    t=t>0?t:-t;
37    p=(n*p%t+t)%t;
38    printf("%I64d\n",p);
39    return 0;
40}