[Chinese remainder theorem - Getting Started] -C ++

Chinese remainder theorem, also known as Chinese remainder theorem, is a congruence method group (see congruence) to solve the ancient Chinese. Number Theory is an important theorem.

This stuff actually have a template in luogu title:
[TJOI2009] Guess

First look at a problem:

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

Primary Mathematics familiar to you learned it
This is the basic question of the use of the Chinese remainder theorem, problem-solving process has three steps:

  1. Find three numbers: from \ (3 \) and (5 \) \ identify common multiple being \ (7 \) except I \ (1 \) the minimum number \ (15 \) , from \ (3 \ ) and \ (7 \) common multiple of the find are \ (5 \) except I \ (1 \) minimum number \ (21 \) , and finally from the \ (5 \) and (7 \) \ common multiple of in addition to find \ (3 \) \ (1 \) the minimum number of \ (70 \) .
  2. With \ (15 \) multiplied by \ (2 \) ( \ (2 \) as the final result is divided by (7 \) \ remaining number), with \ (21 \) multiplied by \ (3 \) ( \ (3 \) as the final result is divided by (5 \) \ remaining number). Similarly, with \ (70 \) multiplied by \ (2 \) ( \ (2 \) divided by the final result \ (3 \) of the remainder ), then adding the product of three \ (15 * 2 + 21 * 3 + 70 * 2 \) to give and \ (233 \) .
  3. With \ (233 \) divided by \ (3,5,7 \) the least common multiple of the number of three \ (105 \) , to give the remainder \ (23 \) , i.e. \ (233% = 23 105 \) . The remainder 23 is in line with the minimum number of conditions.

You have to admire the wisdom of the ancients

And then look back to the topic (link at the beginning)
\ [\ {Cases} the begin (the n--A_1) | B_1 \\ (the n--A_2) | B_2 \\ ... \\ (the n--a_k) | b_k \ {End Cases } \\ \]
after the deformed congruence equation:
\ [\ Cases the begin {} (n--a_1≡0) \ \\ PMOD} {B_1 (n--a_2≡0) \ \\ .. PMOD} {B_2 . \\ (n-a_k≡0) \ pmod {b_k} \\ \ end {cases} \]

Obviously,
if \ (a≡b \ PMOD {m} \) , then \ (a + c≡b + c \ pmod {m} \) holds.
This is not difficult to understand, to understand a little bit on it.
The above modification then click congruence equation:
\ [\} the begin {\\ n-Cases \ equiv A_1 (\ MOD B_1) \ n-Quad \\ \ equiv A_2 (\ MOD B_2) \ Quad \\ ... \ Quad \\ n \ equiv a_k (\ mod
b_k) \ quad \\ \ end {cases} \\ \] then this is bare to the title of the Chinese remainder Theorem. However, note that because of the subject, we need for each \ (a_i \) for this operation:
$
A [I] = (A [I] \ MOD B [I] + B [I]) MODB [I ];
$

Then also need to pay attention to is that question head because good data (bian) heart (tai), so the need to use a fast ride to prevent the explosion of a long long.
Code:

#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.

Guess you like

Origin www.cnblogs.com/moyujiang/p/11242062.html