zoukankan      html  css  js  c++  java
  • 模板—扩展GCD*2

    有必要重新学一下扩展GCD emmmm。

    主要是扩展GCD求解线性同余方程$ax≡b (mod p)$。

    1.方程有解的充分必要条件:b%gcd(a,p)=0。

      证明:

    • $ax-py=b$
    • 由于求解整数解,ax是gcd(a,p)的整数倍,py也是,所以b是gcd(a,p)的整数倍。

    2.扩展GCD模板

    int exgcd(int a,int b,int &x,int &y)
    {
    	if(b==0){x=1,y=0;return a;}//注意x,y的赋值。
    	int gcd=exgcd(b,a%b,x,y),t=x;
    	x=y;y=t-a/b*y;
    	return gcd;
    }

     3.求解线性同余方程:

    扩展欧几里得可以求解形如$ax-py=b$的解。

    方程可化为$ax≡b (mod p)$,注意b和p的位置。

    令t=gcd(a,p)。方程可化为$frac {a}{t}x-frac{p}{t}y=frac{b}{t}$。exgcd求出$frac {a}{t}x-frac{p}{t}y=1$的一组特解x,y。$x*=b/t,y*=b/t$即可求出一组解。

    而要求最小整数解,可以发现如果x减p,y加a等式仍然成立,所以最小整数解为(x%p+p)%p.

    int GCD(int a,int b){return !b?a:GCD(b,a%b);}
    int exgcd(int a,int b,int &x,int &y)
    {
    	if(b==0){x=1,y=0;return a;}
    	int gcd=exgcd(b,a%b,x,y),t=x;
    	x=y;y=t-a/b*y;
    	return gcd;
    }
    int fcc(int a,int b,int p)
    {	
    	int x,y,t=GCD(a,p);
    	if(b%t)return -1;
    	int tem=b/t;a/=t,p/=t;
    	exgcd(a,p,x,y);
    	x*=tem,y*=tem;
    	return (x%p+p)%p;
    }
    
  • 相关阅读:
    工具
    选择排序
    c#中queue的用法
    c#加密
    话谈c#拷贝
    const与readonly的区别
    WinForm中使MessageBox实现可以自动关闭功能
    c#winform关闭窗口时触发的事件
    委托
    C# STA和MTA线程设置
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11353711.html
Copyright © 2011-2022 走看看