中国剩余定理

//中国剩余定理

# include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int MAXN=50;
LL a[MAXN];
LL b[MAXN];
int k;
LL mul(LL a,LL b,LL mod)
{
   LL res=0;
   while(b){
       if(b&1LL) res=(res+a)%mod;
       a=(a+a)%mod;
       b>>=1;
  }
   return res;
}
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-y*(a/b);
   return d;
}
LL China()
{
   LL ans=0,lcm=1,x,y;
   for(int i=1;i<=k;i++) lcm*=b[i];
   for(int i=1;i<=k;i++){
       LL tp=lcm/b[i];
       exgcd(tp,b[i],x,y);
       x=(x%b[i]+b[i])%b[i];//x要为最小的非负整数解
       ans=(ans+mul(a[i],mul(tp,x,lcm),lcm))%lcm;//三个乘起来可能会爆LL,就需要用快速乘/**/
  }
   return (ans+lcm)%lcm;
}
int main()
{
   scanf("%d",&k);
   for(int i=1;i<=k;i++) scanf("%lld",&a[i]);
   for(int i=1;i<=k;i++) scanf("%lld",&b[i]);
   for(int i=1;i<=k;i++) a[i]=(a[i]%b[i]+b[i])%b[i];//a注意可能是负数/**/
   LL d=China();
   printf("%lld\n",d);
   return 0;
}

//扩展中国剩余定理

# include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int MAXN=1e5+100;
LL ai[MAXN],bi[MAXN];
int n;
LL mul(LL a,LL b,LL mod)
{
   LL res=0;
   while(b){
       if(b&1) res=(res+a)%mod;
       a=(a+a)%mod;
       b>>=1;
  }
   return res;
}
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-y*(a/b);
   return d;
}
LL EXCRT()
{
   LL x,y;
   LL M=bi[1],ans=ai[1];
   for(int i=2;i<=n;i++){
       LL a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;
       LL gcd=exgcd(a,b,x,y),bg=b/gcd;
       if(c%gcd!=0) return -1;//扩展欧几里得判断无解
       x=mul(x,c/gcd,bg);
       ans+=x*M;
       M*=bg;
       ans=(ans%M+M)%M;
  }
   return (ans%M+M)%M;
}
int main()
{
   while(~scanf("%d",&n)){//x=ai[i](mod bi[i]) //ai[i]是结果,bi[i]是模数
       for(int i=1;i<=n;i++) scanf("%lld %lld",&bi[i],&ai[i]);/**/
       LL d=EXCRT();
       printf("%lld\n",d);
  }


   return 0;
}

//扩展中国剩余定理的int128版本,有两处需要注意和LL版不一样,会导致超时或者wa

# include <bits/stdc++.h>
using namespace std;

const int MAXN=1e5+100;
typedef __int128 LL;
LL n,m;
LL ai[MAXN],bi[MAXN];
inline __int128 read(){
   __int128 x=0,f=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){
       if(ch=='-')
           f=-1;
       ch=getchar();
  }
   while(ch>='0'&&ch<='9'){
       x=x*10+ch-'0';
       ch=getchar();
  }
   return x*f;
}
inline void print(__int128 x){
   if(x<0){
       putchar('-');
       x=-x;
  }
   if(x>9)
       print(x/10);
   putchar(x%10+'0');
}
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-y*(a/b);
   return d;
}
LL EXCRT()
{
   LL x,y;
   LL M=bi[1],ans=ai[1];
   for(int i=2;i<=n;i++){
       LL a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;
       LL gcd=exgcd(a,b,x,y),bg=b/gcd;
       if(c%gcd!=0) return -1;//扩展欧几里得判断无解
       x=(x*(c/gcd)%bg+bg)%bg;//不用用快速乘,会T
       ans+=x*M;
       M*=bg;
       //ans=(ans%M+M)%M;//不会爆,所以就不用加了
  }
   return ans;
}
int main()
{
   n=read(),m=read();
   for(int i=1;i<=n;i++){
       bi[i]=read(),ai[i]=read();
  }
   LL d=EXCRT();
   if(d==-1){
       printf("he was definitely lying\n");
  }else{
       if(d>=0&&d<=m){
           printf("%lld\n",d);
      }else{
           printf("he was probably lying\n");
      }
  }

   return 0;
}

//java 扩展中国剩余定理

import java.math.BigInteger;
import java.util.Scanner;

class Node{
   BigInteger x,y,d;
   public Node(BigInteger x,BigInteger y,BigInteger d) {
       this.x=x;this.y=y;this.d=d;
  };
   public Node(){
       
  };
}
public class Main{
   public static void main(String[] args) {
       Scanner sr = new Scanner(System.in);
       int n = sr.nextInt();
       BigInteger x, y;
       BigInteger m = sr.nextBigInteger();
       BigInteger M = sr.nextBigInteger();
       BigInteger ans = sr.nextBigInteger();
       int flag=0;
//       System.out.println(1);
       for(int i=1;i<n;i++) {
           BigInteger a = M;
           BigInteger bi = sr.nextBigInteger();
           BigInteger ai = sr.nextBigInteger();
           BigInteger b = bi;
           BigInteger tmp = ai.add(b).subtract(ans.mod(b));
           BigInteger c = tmp.mod(b);
           Node now=exgcd(a,b);
           BigInteger gcd = now.d;
           x=now.x;y=now.y;
           BigInteger bg=b.divide(gcd);
           if( c.mod(gcd).compareTo(BigInteger.ZERO)!=0 ) flag=-1;
           x = mul(x, c .divide(gcd), bg );
//         b = x * a + b;
           ans=ans.add(x.multiply(M));
           M=M.multiply(bg);
           ans=ans.mod(M).add(M);
           ans=ans.mod(M);
           //System.out.println(111111);
           //System.out.println(ans);
      }
//       System.out.println(1);
//     System.out.println((a + b) % a);
       if(flag==-1){
           System.out.println("he was definitely lying");
      }else{
           if(ans.compareTo(m)<1){
               System.out.println(ans);
          }else{
               System.out.println("he was probably lying");
          }
      }

  }

   private static Node exgcd(BigInteger a, BigInteger b) {
       BigInteger m=BigInteger.ZERO,n=BigInteger.ONE,t,x=BigInteger.ONE,y=BigInteger.ZERO;
       while(b.compareTo(BigInteger.ZERO)>0) {
           t=m;m=x.subtract(a.divide(b).multiply(m));x=t;
           t=n;n=y.subtract(a.divide(b).multiply(n));y=t;
           t=b;b=a.mod(b);a=t;
      }
       Node now= new Node(x,y,a);
       return now;
  }

   private static BigInteger mul(BigInteger a, BigInteger b, BigInteger mod) {
       BigInteger res = BigInteger.ZERO;
       while (b.compareTo(BigInteger.ZERO)==1) {
           if(b.mod(BigInteger.valueOf(2)).compareTo(BigInteger.ONE)==0) {
               res=res.add(a);res=res.mod(mod);
          }
//         a = (a + a) % mod;
           a=a.add(a);a.mod(mod);
           b=b.divide(BigInteger.valueOf(2));
//         b >>= 1;
      }
       return res;
  }
}



posted @   fengzlj  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示