两两互质的情况....如果不互质的话,那么就成了解线性模余方程了..
先看神牛的吧,我的代码好乱,主函数的输入有些不一样
#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);
}
}