• 中国剩余定理详解


    对于一个数x,知道:

    x%m1=a1,x%m2=a2,x%m3=a3.(m1,m2,m3)互质。

    求x。

    我们来形象化一下:

    一个数,%3=1,%5=1,%7=2,这个数是什么?

    稍微试一试发现是16,那么怎么正常地算出来呢?

    我们首先要弄明白一件事:

    如果a%b==c,那么a加上一个b的倍数,%b还是余c。这个还是很显而易见的吧。

    那我我们想要求出的x,可以分为三个数相加

    x=A1+A2+A3.其中A1%3=1,A2%5=1,A3%7=2.A2、3是3的倍数,A1、3是5的倍数,A1、2是7的倍数。

    我们先求A3,A3要满足是5、3的倍数,也要满足%7=2,。

    首先,我们知道它一定是15的倍数,那么我们要知道怎样才能满足%7=2

    如果要求%7=2,只用求出来%7=1,然后再乘2就可以了。

    于是得到了如下方程

    15*t≡1(mod 7)

    似曾相识,这个方程相当于15*t+7*y=1可以用拓展欧几里得求解。

    然后,我们知道t=1,也就是15*1%7=1,所以15*1*2%7就等于2.

    于是A3就等于15*1*2=30,

    以此类推,求出来A1、A2,最后加起来就是答案。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #define REP(i,k,n)  for(LL i=k;i<=n;i++)
    #define in(a) a=read()
    using namespace std;
    typedef long long LL;
    inline LL read(){
        LL x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar())
            if(ch=='-')
                f=-1;
        for(;isdigit(ch);ch=getchar())
            x=x*10+ch-'0';
        return x*f;
    }
    LL T;
    inline void exgcd(LL A,LL B,LL &x,LL &y){
        if(B==0)  x=1,y=0;
        else  exgcd(B,A%B,x,y),T=x,x=y,y=T-A/B*y;
    }
    LL n,a[50],b[50],m[50],t[50];
    LL M=1,ans;
    int main(){
        in(n);
        REP(i,1,n)  in(a[i]),in(b[i]),M=M*a[i];
        REP(i,1,n){
            m[i]=M/a[i];
            LL x,y;
            exgcd(m[i],a[i],x,y);
            t[i]=x;
            ans=((ans+(b[i]*t[i]*m[i])%M+M)%M)%M;
        }
        cout<<ans;
        return 0;
    }
    /*3
    3 1
    5 1
    7 2*/
  • 相关阅读:
    c++ 输出 变量名 字符串(zz.is2120.BG57IV3)
    分页存储过程
    连接字符串
    动软 DBHeper 完全代码
    java 数据库连接字符串
    DOS命令行下常见的错误信息
    点击单元格选择整行,又可编辑单元格
    label里文字中的下划线
    Delphi程序中动态生成控件的方法及应用
    双击dbgrid排序的问题
  • 原文地址:https://www.cnblogs.com/jason2003/p/10552476.html
Copyright © 2020-2023  润新知