兩兩互質的情況....如果不互質的話,那麼就成瞭解線性模餘方程了..
先看神牛的吧,My Code好亂,主函數的輸入有些不一樣
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef __int64 int64;
int64 a[15],b[15];
int64 Extend_Euclid(int64 a, int64 b, int64&x, int64& y)
{
if(b==0)
{
x=1,y=0;
return a;
}
int64 d = Extend_Euclid(b,a%b,x,y);
int64 t = x;
x = y;
y = t - a/b*y;
return d;
}
//求解模線性方程組x=ai(mod ni)
int64 China_Reminder(int len, int64* a, int64* n)
{
int i;
int64 N = 1;
int64 result = 0;
for(i = 0; i < len; i++)
N = N*n[i];
for(i = 0; i < len; i++)
{
int64 m = N/n[i];
int64 x,y;
Extend_Euclid(m,n[i],x,y);
x = (x%n[i]+n[i])%n[i];
result = (result + m*a[i]*x%N)%N;
}
return result;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i = 0; i < n; i++)
scanf("%I64d %I64d",&a[i],&b[i]);
printf("%I64d\n",China_Reminder(n,b,a));
}
return 0;
}
在沒有看模板之前,我是純按照孫子定理表格的計算來的寫的,很醜...
// a[]除數,b[ ]餘數,c[ ] mod a[ ]後的衍數,d[ ] mod lcm的衍數
// sum[]乘率也是逆元 ,tall總和
#include<iostream>
#include<cmath>
using namespace std;
int gcd(int a,int b){
if(b==0) return a;
return gcd(b,a%b);
}
int Ext_gcd(int a,int b,int &x,int &y){
if(b==0) { x=1, y=0; return a; }
int d= Ext_gcd(b,a%b,y,x);
y-= a/b*x;
return d;
}
int Inv(int a,int m){
int d,x,y;
d= Ext_gcd(a,(int)m,x,y);
if(d==1) return (x%m+m)%m;
return -1;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int m,lcm=1;
scanf("%d",&m);
int a[12],b[12],c[12],d[12],sum[12],tall=0;
for(int i=0;i<=11;i++)
c[i]=1,d[i]=1;
for(int i=1;i<=m;i++){
scanf("%d",&a[i]);
lcm=a[i]*lcm/gcd(lcm,a[i]); //// 求最小公倍數
}
for(int i=1;i<=m;i++)
scanf("%d",&b[i]);
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
if(j!=i){
c[i] = a[j]%a[i] *(c[i]%a[i])%a[i];
d[i] = a[j] * d[i]%lcm;
}
}
}
for(int i=1;i<=m;i++){
sum[i] = Inv(c[i],a[i]); //// 求乘率也就是逆元
tall = tall%lcm + sum[i]*d[i]*b[i]%lcm; //// 求出最小的符合條件答數
}
if(tall>lcm) tall %= lcm; //// 求出最小的符合條件答數
printf("%d\n",tall);
}
}