[中国の剰余定理 - スタート] - C ++

また、中国の剰余定理として知られている中国の剰余定理は、(合同参照)古代中国を解決するために、合同法基です。数論が重要な定理です。

このようなものは、実際にluoguタイトルにテンプレートを持っている:
[TJOI2009]ゲス

最初の問題を見て:

在《孙子算经》中有这样一个问题:“今有物不知其数,三三数之剩二(除以3余2),五五数之剩三(除以5余3),七七数之剩二(除以7余2),问物几何?”

あなたに馴染みの主な数学はそれを学びました
これは、中国の剰余定理の使用の基本的な質問ですが、問題解決のプロセスは、3つのステップがあります。

  1. 3つの数字を見つける:から\(3 \)及び(5 \)\識別公倍数ビーイングの\(7 \) I以外は\(1 \)最小数(\ 15 \)から、\(3 \ )\(7 \)である検索の公倍数\(5 \) I以外は\(1 \)最小数(\ 21 \) そして最後から\(5 \)及び(7 \)\の公倍数加えて検索する\(3 \)\(1 \)の最小数(\ 70 \)を
  2. \(15 \)を乗じた\(2 \)(\ (2 \)最終結果がで除算される(7 \)\と残数)、\(21 \)を乗じた\(3 \)(\ (3 \)最終結果がで除算される(5 \)\と同様数)、残り(\ 70 \)を乗じた\(2 \)(\ (2 \)最終結果で割っ\(3 \)余りのを)、次の3つの製品添加\(15 * 2 + 21 * 3 + 70 * 2 \)を与えると、\(233 \)
  3. \(233 \)で割った\(3,5,7 \) 3の数の最小公倍数\(105 \)剰余与えるために、(\ 23 \)を、すなわち\(233%= 23 105 \) 残り23は、条件の最小数と一致しています。

あなたは古代人の知恵を賞賛する必要があります

そしてトピック(冒頭にリンク)に振り返る
B_1 \\(N - A_2)| | B_2 \\ ... \\(N - a_k)| b_kの\ {エンドケース- \ [\ {事例}開始(A_1 N) } \\ \]
変形合同式後:
\ [\ケース} {始める(N - a_1≡0)\ \\ PMOD} {B_1(N - a_2≡0)\ \\ .. PMOD} {B_2 。\\(N-a_k≡0)\ PMOD {b_k} \\ \端{ケース} \]

明らかに、
場合\(\ \ PMOD {M}a≡b) 次いで\(A +c≡b+ C \ PMOD {M}は\) 成り立ちます。
これは、その上に少しを理解することが、理解するのは難しいことではありません。
上記修飾は、その後合同式をクリックしてください:
{\は[\}開始\\ n型ケース\当A_1(\ MOD B_1)\ N-クワッド\\ \当A_2(\ MOD B_2)\クワッド\\ ... \クワッド\\ N \当a_k(\ MOD
b_k)\クワッド\\ \端{場合は} \\ \] これは、中国の剰余定理のタイトルへ裸です。しかし、対象の、私たちはそれぞれのために必要なことに注意してください\(a_iを\)この操作のために:
$
A [I] =([I] \ MOD B [I] + B [I])MODB [I ];
$

そして、また、良好なデータ(総統)の心(TAI)ので、その質問の頭部をであるために注意を払う必要があり、そう長い長いの爆発を防ぐために、高速な乗り心地を使用する必要があります。
コード:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a[110],b[110];
ll k;
inline int read()
{
   int 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<<1)+(x<<3)+(ch^48);
       ch=getchar();
   }
   return x*f;
}
inline ll qmul(ll a, ll b, ll m)
{
    ll res=0;
    while(b>0)
    {
        if(b&1)res=(res+a)%m;
        a=(a+a)%m;
        b>>=1;
    }
    return res;
}
inline void exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1,y=0;
        return;
    }
    exgcd(b,a%b,x,y);
    int tmp=x;
    x=y,y=tmp-a/b*y;
    return;
}
ll China()
{
    ll ans=0,lcm=1;
    for(ll i=1;i<=k;i++)
        lcm*=b[i];
    ll x,y;
    for(ll i=1;i<=k;i++)
    {
        ll p=lcm/b[i];
        exgcd(p,b[i],x,y);
        x=(x%b[i]+b[i])%b[i];
        ans=(ans+qmul(qmul(p,x,lcm),a[i],lcm))%lcm;
    }
    return (ans+lcm)%lcm;
}
int main()
{
    cin>>k;
    for(int i=1;i<=k;i++)
        a[i]=read();
    for(int i=1;i<=k;i++)
        b[i]=read(),a[i]=(a[i]%b[i]+b[i])%b[i];
    cout<<China();
    return 0;
}

OV。

おすすめ

転載: www.cnblogs.com/moyujiang/p/11242062.html