zoukankan      html  css  js  c++  java
  • 拓展中国剩余定理(excrt)

    问题

    求解同余方程组

    其中各个方程的模数为不一定两两互质的整数, 求x的最小非负整数解

    求解

    假设已经求出前k-1个方程组成的同余方程组的一个解为x

    且有M=lcm(mo[1],mo[2],mo[3],...,mo[k-1])

    则前k-1个方程的方程组通解为x+i*M 

    因为M为前面方程模数的最小公倍数,所以M可以整除任意一个模数,所以方程组加上或减去M对于方程的同余性没有影响。

    那么对于加入第k个方程后的方程组

    我们就是要求一个正整数t,使得 x+tM≡yu[k](mod mo[k])

    转化一下上述式子得 tM≡yu[k]x(mod mo[k])

    对于这个式子我们已经可以通过扩展欧几里得求解t

    若该同余式无解,则整个方程组无解, 若有,则前k个同余式组成的方程组的一个解解为xk=x+t*M

    所以整个算法的思路就是求解k次扩展欧几里得

    洛谷 P4777

    #include<bits/stdc++.h>
    using namespace std;
    #define ll __int128
    ll ans,x,y,a,b,c,yu[100005],mo[100005],M,n;
    long long read()//int 128好像只能用快读
    {
        ll f=1,x=0;
        char ss=getchar();
        while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
        while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
        return f*x;
    }
    long long gcd(ll a,ll b)
    {
    	ll c;
    	while(a%b)
    	{
    		c=a%b;
    		a=b;
    		b=c;
    	}
    	return b;
    }
    long long lcm(ll a,ll b)
    {
    	return a/gcd(a,b)*b;
    }
    void exgcd(ll a,ll b)
    {
    	if(b==0)
    	{
    		x=1;y=0;
    		return;
    	}
    	exgcd(b,a%b);
    	ll tem=x;
    	x=y;
    	y=tem-a/b*y;
    }
    long long excrt()
    {
    	M=mo[1];ans=yu[1];//特判第一个方程
    	for(int i=2;i<=n;i++)
    	{
    		exgcd(M,mo[i]);//求解方程 t*M+y*mo[i]=yu[i]-ans;
    		ll gcdd=gcd(M,mo[i]);
    		if((yu[i]-ans)%gcdd!=0)return -1;//如果(yu[i]-ans)不是gcd(M,mo[i])的倍数,则根据裴蜀定理,方程无解
    		x*=(yu[i]-ans)/gcdd;//刚才求出的是方程 t*M+y*mo[i]==gcd(M,mo[i])的解,现在将方程解出的x,y同时扩大倍数,就成了方程真正的解。但y没有用,只是个比例系数,就不管了。
    		ans=ans+x*M;//上面的解析有说,更新答案
    		M=M/gcd(M,mo[i])*mo[i];//更新M的值
    		ans=(ans%M+M)%M;//之前的答案只是一个肯定成立的解,现在把ans改成在当前余数系下的最小非负整数答案
    	}
    	return ans;
    }
    int main()
    {
        n=read();
        for(ll i=1;i<=n;i++)
            mo[i]=read(),yu[i]=read();
        cout<<excrt();
        return 0;
    }
    

      

  • 相关阅读:
    Java.io.outputstream.PrintStream:打印流
    Codeforces 732F. Tourist Reform (Tarjan缩点)
    退役了
    POJ 3281 Dining (最大流)
    Light oj 1233
    Light oj 1125
    HDU 5521 Meeting (最短路)
    Light oj 1095
    Light oj 1044
    HDU 3549 Flow Problem (dinic模版 && isap模版)
  • 原文地址:https://www.cnblogs.com/oierjzy/p/11232187.html
Copyright © 2011-2022 走看看