zoukankan      html  css  js  c++  java
  • [洛谷P4777] [模板] 扩展中国剩余定理

    扩展中国剩余定理,EXCRT。

    题目传送门

    重温一下中国剩余定理。

    中国剩余定理常被用来解线性同余方程组:

    x≡a[1] (mod m[1])

    x≡a[2] (mod m[2])

    ......

    x≡a[n] (mod m[n])

    但是中国剩余定理只能解决m[1]、m[2]......m[n]两两互质的情况。

    对于m[1]、m[2]......m[n]不两两互质的情况,我们需要用其它的方法解决。

    假设我们已经处理到了第i个方程,设ans为前i-1个方程的解,ms为m[1]*m[2]*...*m[i-1]。

    那么前i-1个方程组的通解为ans+t*ms(t为任意值)。

    而这些解不是都满足第i个方程。

    所以我们需要求出一个k,使ans+k*ms≡a[i](mod m[i])。

    设c=a[i]-ans,原同余方程转换为不定方程:k*ms+kk*m[i]=c(kk不重要)。

    使用exgcd求解即可。

    由不定方程的性质,如果(a[i]-ans)不能被gcd(ms,m[i])整除,则无解。

    若有解,令c/=gcd(ms,m[i]),m[i]/=gcd(ms,m[i])。

    k=k*c(注意要mod m[i])求出k的最小非负解(这道题需要快速乘防爆long long)。

    最后更新一下:ans=ans+k*ms,ms=ms*m[i],并让ans取模新的ms得到最小解。

    对于初值:ans=a[1](显然满足第一个方程),ms=m[1]。

    然后从第二个方程开始算就好了。

     1 #include<cstdio>
     2 #define ll long long
     3 
     4 int n;
     5 ll a[100005],m[100005];
     6 ll ms,ans;
     7 
     8 ll exgcd(ll ea,ll eb,ll &x,ll &y)
     9 {
    10     if(!eb)
    11     {
    12         x=1,y=0;
    13         return ea;
    14     }
    15     ll ret=exgcd(eb,ea%eb,y,x);
    16     y-=ea/eb*x;
    17     return ret;
    18 }
    19 
    20 ll mul(ll x,ll y,ll mod)
    21 {
    22     ll ret=0;
    23     while(y)
    24     {
    25         if(y&1)ret=(ret+x)%mod;
    26         x=(x+x)%mod;
    27         y>>=1;
    28     }
    29     return ret;
    30 }
    31 
    32 int main()
    33 {
    34     scanf("%d",&n);
    35     for(int i=1;i<=n;i++)scanf("%lld%lld",&m[i],&a[i]);
    36     ans=a[1],ms=m[1];
    37     for(int i=2;i<=n;i++)
    38     {
    39         ll k,kk;
    40         ll c=((a[i]-ans)%m[i]+m[i])%m[i];
    41         ll g=exgcd(ms,m[i],k,kk);
    42         //if(c%g)return 0;
    43         m[i]/=g,c/=g;
    44         k=mul(k,c,m[i]);
    45         ans=ans+k*ms;
    46         ms*=m[i];
    47         ans=(ans%ms+ms)%ms;
    48     }
    49     printf("%lld",ans);
    50     return 0;
    51 }
  • 相关阅读:
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第一题
    fiddler模拟发送post请求
  • 原文地址:https://www.cnblogs.com/eternhope/p/9726466.html
Copyright © 2011-2022 走看看