中国剩余定理和扩展中国剩余定理
#include <iostream> #include <cstdio> #define ll long long using namespace std; void exgcd(ll a,ll b,ll &g,ll &x,ll &y) { if(b==0) { g=a; x=1;y=0; } else {exgcd(b,a%b,g,y,x);y-=(a/b)*x;} } ll China(int n,ll *m,ll *a){ ll M=1,d,y,x=0; for(int i=0;i<n;i++) M*=m[i]; for(int i=0;i<n;i++){ ll w=M/m[i]; exgcd(m[i],w,d,d,y); x=(x+y*w*a[i])%M; } return (x+M)%M; } ll m[15],a[15]; int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lld%lld",&m[i],&a[i]); printf("%lld",China(n,m,a)); }
除数不全为素数
#include <iostream>//hdu3579 #include <cstdio> #include <string> #define ll long long using namespace std; const int maxn=1e5+10; int T,n; ll m[maxn],r[maxn]; ll exgcd(ll a,ll b,ll &x,ll &y) { if(!b){x=1;y=0;return a;} ll re=exgcd(b,a%b,x,y);ll tmp=x; x=y;y=tmp-(a/b)*y; return re; } ll work() { ll M=m[1],R=r[1],x,y,d; for(int i=2;i<=n;i++){ d=exgcd(M,m[i],x,y); if((r[i]-R)%d) return -1; x=(r[i]-R)/d*x%(m[i]/d); R+=x*M; M=M/d*m[i]; R%=M; } return R>0?R:R+M; } int main() { scanf("%d",&T); for(int k=1;k<=T;k++){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&m[i]); for(int i=1;i<=n;i++) scanf("%lld",&r[i]); printf("Case %d: %lld\n",k,work()); } return 0; }