#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<set> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) const int INF=0x3f3f3f3f; typedef long long LL; LL M[15],B[15]; int t; LL n,m,p,num; LL exgcd(LL a, LL b, LL &x, LL &y) { if (!b) { x = 1; y = 0; return a; } LL gcd = exgcd(b, a % b, x, y); LL t = x; x = y; y = t - (a / b) * x; return gcd; } LL mult(LL a,LL b,LL p) { LL ans=0; while(b) { if(b&1) ans=(ans+a)%p; b>>=1; a=(a+a)%p; } return ans; } LL inverse(LL num, LL mod) { LL x, y; exgcd(num, mod, x, y); return (x % mod + mod) % mod; } LL C(LL a, LL b, LL mod) { if (b > a) return 0; LL t1 = 1, t2 = 1; for (int i = 1; i <= b; ++i) { t2 *= i; t2 %= mod; t1 *= (a - i + 1); t1 %= mod; } return mult(t1,inverse(t2, mod),mod); } LL lucas(LL n, LL m, LL p) { if (m == 0) return 1; return mult(C(n % p, m % p, p),lucas(n / p, m / p, p),p); } LL China(LL m[],LL b[],int k)//m:模数 b:余数 { LL n=1,xx,yy; LL ans=0; for(int i=0;i<k;i++) n*=M[i]; for(int i=0;i<k;i++) { LL t=n/M[i]; exgcd(t,M[i],xx,yy); LL x1=mult(xx,t,n); LL x2=mult(x1,b[i],n); ans=(ans+x2)%n; } return (ans%n+n)%n; } int main() { scanf("%d",&t); while(t--) { scanf("%lld%lld%lld",&n,&m,&num); for(int i=0;i<num;i++) { scanf("%d",&p); M[i]=p; B[i]=lucas(n,m,p); } LL ans=China(M,B,num); printf("%lld\n",ans); } return 0; }
原文:http://www.cnblogs.com/zxhl/p/4870487.html