您的位置:首页 > 其它

HDU 5446 Unknown Treasure Lucas+中国剩余定理+按位乘

2016-01-06 15:39 417 查看
HDU 5446 Unknown Treasure
题意:求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 }


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: