HDU 5446 Unknown Treasure Lucas+中国剩余定理+按位乘
题意:求C(n, m) %(p[1] * p[2] ··· p[k]) 0< n,m < 1018
思路:这题基本上算是模版题了,Lucas定理求C(n,m),再用中国剩余定理合并模方程,因为LL相乘会越界,所以用到按位乘。
1 #include <iostream> 2 #include <cstdio> 3 #include <fstream> 4 #include <algorithm> 5 #include <cmath> 6 #include <deque> 7 #include <vector> 8 #include <queue> 9 #include <string> 10 #include <cstring> 11 #include <map> 12 #include <stack> 13 #include <set> 14 #define LL long long 15 #define eps 1e-8 16 #define INF 0x3f3f3f3f 17 #define MAXN 10005 18 #define MAXK 15 19 using namespace std; 20 LL p[MAXK], mod[MAXK]; 21 LL quick_mod(LL x, LL y, LL mod){ 22 if (y == 0) return 1; 23 LL res = quick_mod(x, y >> 1, mod); 24 res = res * res % mod; 25 if (y & 1){ 26 res = res * x % mod; 27 } 28 return res; 29 } 30 LL comb(LL n, LL m, LL p){ 31 LL res = 1; 32 for (int i = 1; i <= m; i++){ 33 LL x = (n + i - m) % p; 34 LL y = i % p; 35 res = res * (x * quick_mod(y, p - 2, p) % p) % p; 36 } 37 return res; 38 } 39 LL lucas(LL n, LL m, LL p){ 40 if (m == 0) return 1; 41 return lucas(n / p, m / p, p) * comb(n % p, m % p, p) % p; 42 } 43 44 LL exgcd(LL a, LL b, LL & x, LL & y) 45 { 46 if (b == 0){ 47 x = 1; 48 y = 0; 49 return a; 50 } 51 else{ 52 LL temp = exgcd(b, a % b, x, y); 53 LL t = y; 54 y = x - y * (a / b); 55 x = t; 56 return temp; 57 } 58 } 59 LL multi(LL a, LL b, LL m){ 60 LL res = 0; 61 while (b){ 62 if (b & 1){ 63 res = (res + a) % m; 64 } 65 a = (a + a) % m; 66 b >>= 1; 67 } 68 return (res + m) % m; 69 } 70 LL china(LL p[], LL mod[], LL m){ 71 LL M = 1; 72 for (int i = 1; i <= m; i++){ 73 M *= p[i]; 74 } 75 LL x, y, res = 0; 76 LL d; 77 for (int i = 1; i <= m; i++){ 78 LL s = M / p[i]; 79 d = exgcd(p[i], s, d, y); 80 res = (res + multi(multi(y, s, M), mod[i], M)) % M; 81 } 82 return res; 83 } 84 int main() 85 { 86 #ifndef ONLINE_JUDGE 87 freopen("in.txt", "r", stdin); 88 //freopen("out.txt", "w", stdout); 89 #endif // OPEN_FILE 90 int T; 91 scanf("%d", &T); 92 LL n, m, k; 93 while (T--){ 94 scanf("%I64d%I64d%I64d", &n, &m, &k); 95 for (int i = 1; i <= k; i++){ 96 scanf("%I64d", &p[i]); 97 mod[i] = lucas(n, m, p[i]); 98 } 99 LL ans = china(p, mod, k); 100 printf("%I64d\n", ans); 101 } 102 }