また、中国の剰余定理として知られている中国の剰余定理は、(合同参照)古代中国を解決するために、合同法基です。数論が重要な定理です。
このようなものは、実際にluoguタイトルにテンプレートを持っている:
[TJOI2009]ゲス
最初の問題を見て:
在《孙子算经》中有这样一个问题:“今有物不知其数,三三数之剩二(除以3余2),五五数之剩三(除以5余3),七七数之剩二(除以7余2),问物几何?”
あなたに馴染みの主な数学はそれを学びました
これは、中国の剰余定理の使用の基本的な質問ですが、問題解決のプロセスは、3つのステップがあります。
- 3つの数字を見つける:から\(3 \)及び(5 \)\識別公倍数ビーイングの\(7 \) I以外は\(1 \)最小数(\ 15 \)から、\(3 \ )と\(7 \)である検索の公倍数\(5 \) I以外は\(1 \)最小数(\ 21 \) 、そして最後から\(5 \)及び(7 \)\の公倍数加えて検索する\(3 \)\(1 \)の最小数(\ 70 \)を。
- \(15 \)を乗じた\(2 \)(\ (2 \)最終結果がで除算される(7 \)\と残数)、\(21 \)を乗じた\(3 \)(\ (3 \)最終結果がで除算される(5 \)\と同様数)、残り(\ 70 \)を乗じた\(2 \)(\ (2 \)最終結果で割っ\(3 \)余りのを)、次の3つの製品添加\(15 * 2 + 21 * 3 + 70 * 2 \)を与えると、\(233 \) 。
- \(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。