zoukankan      html  css  js  c++  java
  • 扩展欧几里得及中国剩余定理

    Exgcd

    扩展欧几里得

    void exgcd(int a,int b,int &x,int &y){
    	if(!b){x=1,y=0;return;}
    	exgcd(b,a%b,x,y);b-=y*(a/b);
    }
    

    对于 (gcd(a,b)=g)(a imes k_1+b imes k_2 =g)

    通过 (exgcd(a,b,x,y)) (k_1=x+k imes b)

    对于 (gcd(a,b)=g)(a imes k_1+b imes k_2=C imes g)

    通过 (exgcd(a,b,x,y)) (k_1 = x imes C+k imes b)

    中国剩余定理

    这里只讨论不互质的扩展情况

    证明

    现在有两条式子:

    (X=a_1 imes k_1+b1)

    (X=a_2 imes k_2+b_2)

    可得恒等式

    (a_1 imes k_1-a_2 imes k_2=b_2-b_1)

    那么可以通过(exgcd)求出 (k_1) 的一组解

    设合并上面两式的结果为 (X=a_3 imes k_3+b_3)

    那么有 (a_3 imes k_3+b_3=a_1 imes k_1+b_1)

    易得 (a_3=lcm(a_1,a_2))

    (b_3=(a_1 imes k_1+b_1)\%a_3)

    struct CRT{
    	static const int M=2888;
    	LL A[M],B[M];
    	int sz;
    	void insert(int a,int b){A[++sz]=a,B[sz]=b;}
    	LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
    	void exgcd(LL a,LL b,LL &x,LL &y){
    		if(!b){x=1,y=0;return;}
    		exgcd(b,a%b,y,x);y-=(a/b)*x;
    	}
       LL Exgcd(LL A,LL B,LL C){
       	LL x,y;
          exgcd(A,B,x,y);
          return (x*C%B+B)%B;
       }
    	LL Solve(){
    		FOR(i,1,sz-1){
    			LL C=B[i+1]-B[i],g=gcd(A[i],A[i+1]);
    			if(C%g)return -1;//无解
    			C/=g;
    			LL k1=Exgcd(A[i]/g,A[i+1]/g,C);
    			A[i+1]=A[i]/g*A[i+1];
             B[i+1]=(A[i]*k1+B[i])%A[i+1];
          }
          return B[sz];
    	}
    }CT;
    
  • 相关阅读:
    c语言中srand和rand函数 生成随机数总结
    枚举类型
    VS2008快捷键使用技巧
    PV实现同步
    PV操作(深入显出)
    数字在排序数组中出现的次数
    两个链表的第一个公共结点
    数组中的逆序对
    第一个只出现一次的字符位置
    丑数
  • 原文地址:https://www.cnblogs.com/Zerokei/p/9898218.html
Copyright © 2011-2022 走看看