zoukankan      html  css  js  c++  java
  • 解线性同余方程组

    想必学完exgcd的各位dalao们都已经明白如何求解同余方程了

    今天本蒟蒻只是想讲讲线性同余方程组的解法供各位大佬批评指错

    我们现在有一些线性同余方程

    X=b1 (mod a1)

    X=b2 (mod a2)

    ...

    X=bn (mod an)

    对于前面第一个方程,我们可以用exgcd求出一个X满足一式

    不妨设X=a1*y1+b1

    若存在X满足二式,则a1*y1+b1=b2 (mod a2)

    所以y1=(b2-b1)/a1 (mod a2)

    该式有解当且仅当(b2-b1)|gcd(a1,a2)

    所以a1y1+a2y2=b2-b1

    那么我们就可以用exgcd求出y1的解,进而求出X

    那么问题来了,一式二式合并后是什么呢?

    我们可以证明在lcm(a1,a2)中有且仅有一个X满足条件,利用一些初中同余知识就可以,在这里就不详细证明了

    由此我们得到一个新方程X=X(mod lcm(a1,a2))

    用这个方程再和后面的方程合并,for example,anslcm(a1,a2)+a3y3=b3-X

    这样一个一个往下求便可以求出答案

    下面是一个裸的模板

    #include<cstdio>	
    #define ll long long 			
    ll x,m,M,r,y,z;
    ll gcd(ll a,ll b) {return a%b==0 ? b:gcd(b,a%b);} 
    void inv(ll a,ll b) {
    	if (a%b==0) 
    	{z=0; y=1; return;}
    	inv(b,a%b);
    	ll r=z;
    	z=y,y=r-a/b*y;
    }
    int main()
    {
    	int n;
    	scanf("%d",&n);
    	x=0; m=1;
    	for (int i=1;i<=n;i++){
    		scanf("%lld%lld",&M,&r);
    		ll b=r-x,d=gcd(m,M);
    		if (b%d!=0) {
    			printf("-1");
    			return 0;
    		}
    		inv(m/d,M/d);
    		ll t=b/d*z%(M/d);
    		x=x+m*t;
    		m*=M/d;
    	}
    	printf("%lld
    
    ",x>0 ? x:x+m);
    	return 0;
    }
    
  • 相关阅读:
    9、二叉排序树的创建、插入、遍历
    8、判断两个链表是否相交
    7、判断链表是否有环
    6、查找单链表中倒数第n个节点
    5、单链表的反转
    4、KMP(看毛片)算法
    3、希尔排序
    2、快速排序
    json字符串转为json对象
    json对象转化为字符串过程分析
  • 原文地址:https://www.cnblogs.com/Cool-Angel/p/8403536.html
Copyright © 2011-2022 走看看