【數論】中國剩余定理


百度百科

Pre-Knowledge

    乘法逆元

 Definition&Solution

  對於求解一元不定方程組的一種算法叫做中國剩余定理。又名孫子定理。

   求解方法:記tot=∏mi,Mi=tot/ai,即Mi為除ai以外所有a的乘積。

   記ti為Mi在Mod mi意義下的逆元。求解單個逆元的方法見前置知識

   則方程組的唯一解為x≡Σ(ai*ti*Mi)  (Mod tot)

    下面的例題給出了一個中國剩余定理的典型應用

Example

傳送門

Description

  自從曹沖搞定了大象以后,曹操就開始捉摸讓兒子干些事業,於是派他到中原養豬場養豬,可是曹沖滿不高興,於是在工作中馬馬虎虎,有一次曹操想知道母豬的數量,於是曹沖想狠狠耍曹操一把。舉個例子,假如有16頭母豬,如果建了3個豬圈,剩下1頭豬就沒有地方安家了。如果建造了5個豬圈,但是仍然有1頭豬沒有地方去,然后如果建造了7個豬圈,還有2頭沒有地方去。你作為曹總的私人秘書理所當然要將准確的豬數報給曹總,你該怎么辦?

Input

  第一行包含一個整數n表示 建立豬圈的次數,解下來n行,每行兩個整數。表示建立了ai個豬圈,有bi頭豬沒有去處。你可以假定ai,aj互質.

Output

  輸出包含一個正整數,即為曹沖至少養母豬的數目。

Sample Input

3
3 1
5 1
7 2

Sample Output

16

Hint

  n<=10;

  bi<=ai<=1000

  保證輸入合法。

Solution

  不難發現這是一道中國剩余定理的裸題。按照算法計算即可。

Code

#include<cstdio>
#define ll long long int
#define maxn 25

inline void qr(ll &x) {
    char ch=getchar();ll f=1;
    while(ch>'9'||ch<'0')    {
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')    x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x*=f;
    return;
}

inline ll max(ll a,ll b) {return a>b?a:b;}
inline ll min(ll a,ll b) {return a<b?a:b;}

inline void swap(ll &a,ll &b) {
    ll c=a;a=b;b=c;return;
}

ll n,m[maxn],ans,b[maxn],a[maxn],t[maxn],tot=1,x,y,MOD;

void exgcd(ll a,ll b,ll&fx,ll&fy) {
    if(!b) {
        MOD=a;fx=1;fy=0;return;
    }
    ll gx,gy;
    exgcd(b,a%b,gx,gy);
    fx=gy;
    fy=gx-(a/b)*gy;
    return;
}

int main() {
    qr(n);
    for(int i=1;i<=n;++i) {
        qr(a[i]);qr(b[i]);
        tot*=a[i];
    }
    for(int i=1;i<=n;++i) {
        m[i]=tot/a[i];
        a[i]*=-1;
        exgcd(m[i],a[i],t[i],y);
        a[i]*=-1;
        if(MOD<0)    t[i]=-t[i];
        while(t[i]<=0) t[i]+=a[i];
        ans+=b[i]*t[i]%tot*m[i]%tot;
        ans%=tot;
    }
    while(ans>0)    ans-=tot;
    while(ans<=0)  ans+=tot;
    printf("%lld\n",ans);
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM