Solution
\ [x \ equiv \ left \
{\ begin {aligned} a_1 \ mod p_1 \\ a_2 \ mod p_2 \\ ... \\ a_n \ mod p_n \ end {aligned} \ right. \] Wherein \ (P_i \) is a prime number
If positive integer solution, the minimum output, and if not, the output Impossible
Front cheese:
\ (exgcd \) seeking multiplicative inverse
That is to say, seeking \ (X \) such that \ (ax \ equiv 1 \ mod b \)
Corresponds seeking \ (ax = kb + 1 \ )
Transposition
\ [ax-kb = 1 \
] provided \ (Y = -k \)
\ [= AX +. 1 by \]
This significant thing \ (exgcd \) can engage them
Then started
Chinese remainder theorem \ ((the CRT) \)
\ [X \ equiv \ left \ {\ the aligned the begin {A_1} \ \\ MOD P_1 A_2 \ \\ ... \\ MOD P_2 A_N \ MOD P_n \ the aligned End {} \ right. \]
provided \ (M = p_1 * p_2 * ... * p_n, m_i = \ frac {M} {p_i} \)
Since \ (p_i \) is a prime number, so \ ([0, M-1 ] \) have the range of one and only one solution (the own emotional understanding will know)
So we just an arbitrary solution, then it \ (M \) taken like membrane
We assume that
\ [ans_i \ equiv \ left \
{\ begin {aligned} a_i \ mod p_i \\ 0 \ mod m_i \ end {aligned} \ right. \] Then the \ (ans_i \) he do anything extraordinary ? It just satisfies \ (\ equiv a_i \ mod p_i \) and does not "affect" the other \ (a_j, p_j \)
The answer is $ ans = \ sum_ {i = 1} ^ nans_i% M $
So how do we find $ ans_i $?
First of all, \ (ans_i \) is (m_i \) \ multiples, so we set \ (ans_i = k_i * m_i \ )
Then we have to allow him to meet \ (\ equiv a_i \ MOD P_i \) , then we set \ (k_i = a_i * t_i \ )
That \ (ans_i = m_i * a_i * t_i \)
We want
\ [m_i * t_i \ equiv 1
\ mod p_i \] is seeking a \ (m_i \) in \ (\ mod p_i \) multiplicative inverse in the sense of the thing, \ (exgcd \) wave
Is then calculated for each \ (ans_i \) plus one plus taken membranes, did not
Time complexity \ (O (nlog M) \ )
// This code Write By chtholly_micromaker(MicroMaker)
#include <cstdio>
#include <cctype>
#define int long long
#define reg register
using namespace std;
const int MaxN=15;
template <class t> inline void rd(t &s)
{
s=0;
reg char c=getchar();
while(!isdigit(c))
c=getchar();
while(isdigit(c))
s=(s<<3)+(s<<1)+(c^48),c=getchar();
return;
}
inline int exgcd(int a,int b,int &x,int &y)
{
if(!b)
{
x=1,y=0;
return a;
}
reg int c=exgcd(b,a%b,y,x);
y-=a/b*x;
return c;
}
int n,mulsum;
int a[MaxN],p[MaxN];
inline int crt()
{
reg int ans=0,mi,x,y;
for(int i=1;i<=n;++i)
{
mi=mulsum/p[i];
exgcd(p[i],mi,x,y);
ans=(ans+a[i]*mi*y)%mulsum;
}
return (ans+mulsum)%mulsum;
}
inline void work()
{
mulsum=1;
rd(n);
for(int i=1;i<=n;++i)
{
rd(p[i]);rd(a[i]);
mulsum*=p[i];
}
printf("%lld\n",crt());
return;
}
signed main(void)
{
int t;rd(t);
for(int i=1;i<=t;++i)
printf("Case %lld: ",i),work();
return 0;
}