HDU1576 A/B(扩展欧几里得)

要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
Input
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
Output
对应每组数据输出(A/B)%9973。
Sample Input
2
1000 53
87 123456789
Sample Output
7922
6060

#include

int GCD;

int exgcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    GCD=exgcd(b,a%b,x,y);//return就是return到这一步的下一步;保存最大公约数(即最后一步的a)用来求一般解(一般解就是等于号右边为n,不是通解),x=x1*(n/GCD) 
    int t=x;
    x=y;
    y=t-(a/b)*y;
}

int main()
{
    int t,b,n,x,y;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&b);
        exgcd(b,9973,x,y);
        x=x*n;
        printf("%d\n",((x%9973)+9973)%9973);//如果x为负则转换为最小的正数,如果为正这样转换还是会转换为最小的正数啦 
    }
    return 0; 
}

(自己写的推导在挑战程序设计116)

扩展欧几里得理解为对于两个不全为0的整数a,b,必存在一组解x,y使得
ax+by==gcd(a,b)

x1,y1记作上一步的解,那么下一步的解x=y1,y=x1-(a/b)*y1;

特解:x,y;

求(特解的)一般解:
求符合ax+by==n的解x2,y2:
x2=x*(n/gcd(a,b));
y2=y*(n/gcd(a,b));

懵了吧?gcd(a,b)等于多少??注意就是代码里的GCD,GCD的作用就在这。
因为本题gcd(b,9973)==1,所以记录不记录都没关系~(x2=x*n/1,y2=y*n/1);

求通解:
神马是通解?

就是高中解一元二次方程y=kx+b,给你一组x,y(特解),你可以求出k和b(比如k=2,b=3),那么y=2x+3就是通解,x=(y-3)/2就是通解;(通解就是这条函数上的所有点)

通解x3,y3怎么求:

GCD还是代码中的GCD表示gcd(a,b),a,b的最大公约数;

x3=x2+b/(d*t);
y3=y2-a/(d*t);
(是x2,y2吧?应该是)
呐,t为任意常整数。

栗……子:
ax+by=3//这是对照~
3x+0y=3 x2=1,y2=0;//if(b==0) return;①
6x+3y=3 x1=y2=0,y1=x2-(a/b)*y2=1-(6/3)*0=1;
9x+6y=3 x0=y1=1,y0=x1-(a/b)*y1=0-(9/6)*1=-1;

呐,这样9x+6y=3的一组解就找到了 是x0=1,y0=-1。

神马?没看懂??

递推..当然是从下往上看啦~

辗转相除法其实就是:

a b


b a%b

(a转换为上一步的b,b转换为上一步的a%b)

嗯。暂就酱,关于通解还没有做题应用,以后再补充叭。

补充:
①为什么最后当b==0时的解是x=1,y=0:
ax+by==gcd(a,b)
然后b为0了
ax+by==gcd(a,0)==a//(你看我也不懂为什么gcd(a,0)==a ②)
解叭解叭。

②为什么gcd(a,0)==a?:
0除以任何一个数都得0 可以整除
所以0与一个数的最大公约数是这个数本身

你可能感兴趣的:(笔记,ACM,数论只会GCD)