HDU 5446 Unknown Treasure

Unknown Treasure

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 721    Accepted Submission(s): 251

Problem Description

On the way to the next secret treasure hiding place, the mathematician discovered a cave unknown to the map. The mathematician entered the cave because it is there. Somewhere deep in the cave, she found a treasure chest with a combination lock and some numbers on it. After quite a research, the mathematician found out that the correct combination to the lock would be obtained by calculating how many ways are there to pick m different apples among n of them and modulo it with M. M is the product of several different primes.

Input

On the first line there is an integer $T(T\leq 20)$ representing the number of test cases.

Each test case starts with three integers $n,m,k(1\leq m\leq n\leq 10^{18},1\leq k\leq 10)$ on a line where k is the number of primes. Following on the next line are k different primes p1,...,pk. It is guaranteed that $M=p_1⋅p_2\cdots p_k\leq 10^{18}\, and\, p_i\leq 10^5 for\, every\, i\in\{1,\dots,k\}.$

Output

For each test case output the correct combination on a line.

Sample Input

1

9 5 2

3 5

Sample Output

6

Source

2015 ACM/ICPC Asia Regional Changchun Online

解题:中国剩余定理+Lucas定理

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 101010;
 5 LL F[maxn] = {1},a[maxn],m[maxn],N,M,n;
 6 void init(LL mod){
 7     for(int i = 1; i < maxn; ++i)
 8         F[i] = F[i-1]*i%mod;
 9 }
10 LL quickPow(LL base,LL index,LL mod){
11     LL ret = 1;
12     base %= mod;
13     while(index){
14         if(index&1) ret = ret*base%mod;
15         index >>= 1;
16         base = base*base%mod;
17     }
18     return ret;
19 }
20 LL Inv2(LL b,LL mod){
21     return quickPow(b,mod-2,mod);
22 }
23 LL Lucas(LL n,LL m,LL mod){
24     LL ret = 1;
25     while(n && m){
26         LL a = n%mod;
27         LL b = m%mod;
28         if(a < b) return 0;
29         ret = ret*F[a]%mod*Inv2(F[b]*F[a-b]%mod,mod)%mod;
30         n /= mod;
31         m /= mod;
32     }
33     return ret;
34 }
35 LL mul(LL a,LL b,LL mod){
36     if(!a) return 0;
37     return ((a&1)*b%mod + (mul(a>>1,b,mod)<<1)%mod)%mod;
38 }
39 LL CRT(LL a[],LL m[],LL n){
40     LL M = 1,ret = 0;
41     for(int i = 0; i < n; ++i) M *= m[i];
42     for(int i = 0; i < n; ++i){
43         LL x,y,tm = M/m[i];
44         x = Inv2(tm,m[i]);
45         ret = (ret + mul(mul(tm,x,M),a[i],M))%M;
46     }
47     return ret;
48 }
49 int main(){
50     int kase;
51     scanf("%d",&kase);
52     while(kase--){
53         scanf("%I64d%I64d%I64d",&N,&M,&n);
54         for(int i = 0; i < n; ++i){
55             scanf("%I64d",m + i);
56             init(m[i]);
57             a[i] = Lucas(N,M,m[i]);
58         }
59         printf("%I64d\n",CRT(a,m,n));
60     }
61     return 0;
62 }

时间: 2024-08-05 14:53:43

HDU 5446 Unknown Treasure的相关文章

hdu 5446 Unknown Treasure lucas和CRT

Unknown Treasure Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5446 Description On the way to the next secret treasure hiding place, the mathematician discovered a cave unknown to the map. The mathematician ent

hdu 5446 Unknown Treasure 卢卡斯+中国剩余定理

Unknown Treasure Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description On the way to the next secret treasure hiding place, the mathematician discovered a cave unknown to the map. The mathematician

hdu 5446 Unknown Treasure Lucas定理+中国剩余定理

Unknown Treasure Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2209    Accepted Submission(s): 821 Problem Description On the way to the next secret treasure hiding place, the mathematician

HDU 5446 Unknown Treasure(lucas + 中国剩余定理 + 模拟乘法)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5446 题目大意:求C(n, m) % M, 其中M为不同素数的乘积,即M=p1*p2*...*pk, 1≤k≤10.1≤m≤n≤10^18. 分析: 如果M是素数,则可以直接用lucas定理来做,但是M不是素数,而是素数的连乘积.令C(n, m)为 X ,则可以利用lucas定理分别计算出 X%p1,X%p2, ... , X % pk的值,然后用中国剩余定理来组合得到所求结果. 比较坑的地方是,

ACM学习历程—HDU 5446 Unknown Treasure(数论)(2015长春网赛1010题)

Problem Description On the way to the next secret treasure hiding place, the mathematician discovered a cave unknown to the map. The mathematician entered the cave because it is there. Somewhere deep in the cave, she found a treasure chest with a com

Hdu 5446 Unknown Treasure(Lucas+中国剩余定理)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5446 思路:Lucas求出所有a[i]=C(n,m)%m[i],中国剩余定理求出最终结果x (LL*LL会爆掉,手写乘法). 中国剩余定理: 设m1,m2,....mn是两两互质的正整数,对任意给定的整数a1,a2,....an必存在整数,满足 x≡a1 (mod m1),x≡a2 (mod m2),x≡a3 (mod m3)...... 并且满足上列方程组的解x(mod m1m2m3.....mn

HDU 5446 Unknown Treasure(Lucas定理+CRT)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5446 [题目大意] 给出一个合数M的每一个质因子,同时给出n,m,求C(n,m)%M. [题解] 首先我们可以用Lucas定理求出对答案对每个质因子的模,然后我们发现只要求解这个同余方程组就可以得到答案,所以我们用中国剩余定理解决剩下的问题. [代码] #include <cstdio> #include <cstring> #include <algorithm> u

hdu 5446 Unknown Treasure 中国剩余定理+lucas

题目链接 求C(n, m)%p的值, n, m<=1e18, p = p1*p2*...pk. pi是质数. 先求出C(n, m)%pi的值, 然后这就是一个同余的式子. 用中国剩余定理求解. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; #define l

hdu 5446 Unknown Treasure (Lucas定理+中国剩余定理+快速乘)

题意:c( n, m)%M    M = P1 * P2 * ......* Pk (其中Pk是素数) 思路:Lucas定理中C(n,m)%M,M必须是素数,当M不是素数时,我们可以把它拆成素数的乘积 如果x=C(n,m)%M ,M=p1*p2*..*pk;  a[i]=Lucas(n,m)%pi: xΞa[1](mod p1) xΞa[2](mod p2) ... xΞa[k](mod pk) 用中国剩余定理就可以把x求出来 注意到这道题ll*ll 由于计算机底层设计的原因,做加法往往比乘法快