zoukankan      html  css  js  c++  java
  • 扩展中国剩余定理(简介)

    扩展中国剩余定理(普通线性同余不等式组)板子题

    对于中国剩余定理来说,每一个线性同余式所要求的的模数均为素数,这就在一定程度上限制了中国剩余定理的使用(但不能否认这是一个很有用而且很好用的算法)

    因此,我们需要找到一种对于模数不互质的线性同余式组的更普遍的求解算法

    扩展中国剩余定理构造求解

    • 对于一个线性同余方程组:

    • 我们首先假定一个数 (x) 为线性同余式组的前 (k-1) 个解,此时有 (M = lcm ( m1,m2,……,m_i ))

      则对于前 (k-1) 个线性同余式的通解为:(x + i imes M ( i in Z))

      那么对于第 (k) 个线性同余式,我们只需要找到一个数 (t) ,满足 (x + t imes M equiv a_k (mod m_k )) 即可

      整理一下,即可得到:(t imes M equiv a_k - x ( mod m_k )),对于整理得到的式子,我们就可以用扩展欧几里得算法求得 (t) 的值,再对答案进行累加即可

      所以,依次类推,对含有 (k) 个线性同余式的同余式组,只需使用 (k-1) 次扩展欧几里得算法即可求得答案

    下面放代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<math.h>
    #include<algorithm>
    #define ll long long
    using namespace std;
    
    const ll maxn=1e6+10;
    ll ai[maxn],bi[maxn];
    ll n;
    ll M,ans,bx;
    
    inline ll exgcd(ll a,ll b,ll &x,ll &y) //扩展欧几里得
    {
    	if(b==0)
    	{
    		x=1,y=0;
    		return a;
    	}
    	ll d=exgcd(b,a%b,x,y);
    	ll z=x;
    	x=y;
    	y=z-(a/b)*y;
    	return d;
    }
    
    inline ll multi(ll a,ll b,ll p)	 //龟速乘,避免乘法溢出 
    {
    	ll ret=0;
    	
    	while(b)
    	{
    		if(b&1)
    		{
    			ret=(ret+a)%p;
    		}
    		a=(a+a)%p;
    		b>>=1;
    	}
    	return ret;
    }
    
    inline ll crt()     			// excrt 求解 
    {
    	ll x,y,k,t;
    	
    	ll M=bi[1],ans=ai[1];		//初始时对 ans 和  M 进行预处理,将第一个同余式中的模数与余数赋给 M 和 ans ,作为第一组解 
    	
    	for(int i=2;i<=n;i++) 		//注意要进行 n-1 次循环 
    	{
    		ll a=M;
    		ll b=bi[i];
    		ll c=(ai[i]-ans%b+b)%b;  
    		ll g=exgcd(a,b,x,y);	//在进行扩展欧几里得算法时,求解的是 M * x + b[i] * y = gcd( M , b[i] ) 中 x 和 y 的值 , 并可顺便将 gcd( M , b[i] ) 求得 
    		if(c%g!=0) return -1; 	//目标解不能被 gcd ( M , b[i] ) 整除 , 说明该同余式无解 
    		bx=b/g;
    		x=multi(x,c/g,bx);
    		ans+=x*M;		//累加答案 
    		M*=bx;			//求 b[1] 到 b[i] 的 lcm
    		ans=(ans%M+M)%M;
    	}
    	
    	return (ans%M+M)%M;
    }
    
    int main(void)
    {
    	scanf("%lld",&n);
    	
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lld%lld",&bi[i],&ai[i]);
    	}
    	
    	printf("%lld
    ",crt());
    	
    	return 0;
    }
    
  • 相关阅读:
    css去掉点击连接时所产生的虚线边框技巧兼容符合w3c标准的浏览器
    html中<a href> </a>的用法
    点击页面其他地方关闭弹出层
    CSS文字两端对齐
    mouseover和mouseenter的区别
    jquery中的$("#id")与document.getElementById("id")的区别
    console.log
    ie6中margin失效问题
    渐变
    CSS 清除浮动的4种方法
  • 原文地址:https://www.cnblogs.com/jd1412/p/13359831.html
Copyright © 2011-2022 走看看