中国剩余定理

https://www.cnblogs.com/yoyoball/p/9236084.html

中国剩余定理 mod m    m互质

ll ex_gcd(ll a,ll b,ll &x,ll &y){
    if (b==0){x=1; y=0; return a;}
    ll gcd=ex_gcd(b,a%b,x,y),tmp=x;
    x=y; y=tmp-a/b*y;
    return gcd;
}

ll CRT(int *w,int *a,int n){//w数组里面存的是模数,a里面存的是余数
    ll x,y,ret=0,mod=1,tmp;//这里的mod就是相当于上面讲的N啦
    for (int i=1;i<=n;++i) mod*=w[i];
    for (int i=1;i<=n;++i){
        tmp=mod/w[i];
        ex_gcd(w[i],tmp,x,y);
        ret=(ret+y*tmp*a[i])%mod;
    }
    return (ret+mod)%mod;
}

m不互质

ll mul(ll x,ll y,ll mod){//这里mul是为了防止模数特别大的情况下爆出去而用的黑科技
    ll tmp=x*y-(ll)((ll)x/mod*y)*mod;
    return (tmp+mod)%mod;
}
ll ex_gcd(ll a1,ll b1,ll &x,ll &y){
    if (!b1){x=1; y=0; return a1;}
    ll gcd=ex_gcd(b1,a1%b1,x,y),tmp=x;
    x=y; y=tmp-a1/b1*y;
    return gcd;
}
ll inv(ll a1,ll mod){
    ll x,y;
    ll gcd=ex_gcd(a1,mod,x,y);
    if (gcd!=1) return -1;
    return (x%mod+mod)%mod;
}
ll ex_CRT(ll *a,ll *mod,int n){
    ll Mod=mod[1],A=a[1],d,tmp,t,x,y,tmpMod;
    for (int i=2;i<=n;++i){
        d=ex_gcd(Mod,mod[i],x,y);
        tmp=a[i]-A;
        if (tmp%d) 
            return -1;//不能整除就无解
        tmpMod=Mod/d*mod[i];
        A=(A+mul(mul(Mod,inv(Mod/d,mod[i]/d),tmpMod),tmp/d,tmpMod))%tmpMod;
        Mod=tmpMod;
    }
    return (A%Mod+Mod)%Mod;
}

java 不互质

import java.io.*;
import java.util.*;
import java.*;
import java.math.*;
public class Main {
	static BigInteger a[]=new BigInteger[105];
	static BigInteger mod[]=new BigInteger[105];
	static BigInteger zero=BigInteger.ZERO;
	static BigInteger temp1,temp2;
	static BigInteger mul(BigInteger x,BigInteger y,BigInteger mod){//这里mul是为了防止模数特别大的情况下爆出去而用的黑科技
	    BigInteger tmp=x.multiply(y).subtract(x.divide(mod).multiply(y).multiply(mod));
	    return (tmp.add(mod)).remainder(mod);
	}
	static BigInteger ex_gcd(BigInteger a1,BigInteger b1,BigInteger tempx[],BigInteger tempy[]){
	    if (b1==zero){
	    	tempx[0]=BigInteger.ONE; 
	    	tempy[0]=BigInteger.ZERO; 
	    	return a1;
	    	}
	    BigInteger gcd=ex_gcd(b1,a1.remainder(b1),tempx,tempy),tmp=tempx[0];
	    tempx[0]=tempy[0]; 
	    tempy[0]=tmp.subtract((a1.divide(b1)).multiply(tempy[0]));
	    //System.out.println(tempx[0]+" "+tempy[0]+" "+gcd);
	    return gcd;
	}
	static BigInteger inv(BigInteger a1,BigInteger mod){
	    BigInteger xx[]=new BigInteger [2];
	    BigInteger yy[]=new BigInteger [2];
	    BigInteger gcd=ex_gcd(a1,mod,xx,yy);
	    //System.out.println(xx[0]+" "+yy[0]+" "+gcd);
	    //System.out.println((xx[0].remainder(mod).add(mod)).remainder(mod));
	    if (gcd.equals(BigInteger.ONE)) 
	    	return (xx[0].remainder(mod).add(mod)).remainder(mod);
	    return BigInteger.valueOf(-1);
	}
	static BigInteger ex_CRT(BigInteger a[],BigInteger mod[],int n){
	    BigInteger Mod=mod[1],A=a[1],d,tmp,t,tmpMod;
	    BigInteger x[]=new BigInteger [2];
	    BigInteger y[]=new BigInteger [2];
	    for (int i=2;i<=n;++i){
	        d=ex_gcd(Mod,mod[i],x,y);
	        tmp=a[i].subtract(A);
	        if (tmp.remainder(d)!=BigInteger.ZERO)
	            return BigInteger.valueOf(-1);//不能整除就无解
	        tmpMod=Mod.divide(d).multiply(mod[i]);
	        //System.out.println(d);
	        //System.out.println(Mod.divide(d)+" "+mod[i].divide(d));
	        //System.out.println(inv(Mod.divide(d),mod[i].divide(d)));
	        
	        BigInteger test=inv(Mod.divide(d),mod[i].divide(d));
	        //System.out.println(test);
	        test=mul(Mod,test,tmpMod);
	        //System.out.println(test);
	        test=mul(test,tmp.divide(d),tmpMod);
	        //System.out.println(test);
	        A=(A.add(test)).remainder(tmpMod);
	        Mod=tmpMod;
	        //System.out.println(A);
	    }
	    return (A.remainder(Mod).add(Mod)).remainder(Mod);
	}
	public static void main(String args[]) throws Exception {
        	Scanner cin=new Scanner(System.in);
        	int num = cin.nextInt();
        	BigInteger upperbound;
            upperbound = cin.nextBigInteger();
        	for(int i=1;i<=num;i++){
        		mod[i] = cin.nextBigInteger();
        		a[i] = cin.nextBigInteger();
        	}
        	BigInteger ans=(ex_CRT(a,mod,num));
        	if(ans==BigInteger.valueOf(-1)){
        		System.out.println("he was definitely lying");
        	}
        	else{
        		if(ans.compareTo(upperbound)>0){
        			System.out.println("he was probably lying");
        		}
        		else{
        			System.out.println(ans);
        		}
        	}
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值