BZOJ2982:combination(Lucas)

本文介绍了一个使用Lucas定理解决大规模组合数计算问题的方法,通过模运算求解C(n,m)的值,并提供了完整的C++代码实现。

Description

LMZn个不同的基友,他每天晚上要选m个进行[河蟹],而且要求每天晚上的选择都不一样。那么LMZ能够持续多少个这样的夜晚呢?当然,LMZ的一年有10007天,所以他想知道答案mod 10007的值。(1<=m<=n<=200,000,000)

Input

  第一行一个整数t,表示有t组数据。(t<=200)
  接下来t行每行两个整数n, m,如题意。

Output

T行,每行一个数,为C(n, m) mod 10007的答案。

Sample Input

4
5 1
5 2
7 3
4 2

Sample Output

5
10
35
6

Solution

Lucas模板

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define N (50000+1000)
 5 #define MOD (10007)
 6 using namespace std;
 7 
 8 int fac[N],facInv[N],inv[N],T,n,m;
 9 
10 void Init(int p)
11 {
12     fac[0]=1; inv[1]=1; facInv[0]=1;
13     for (int i=1; i<=p; ++i)
14     {
15         if (i!=1) inv[i]=(p-p/i)*inv[p%i]%p;
16         fac[i]=fac[i-1]*i%p; facInv[i]=facInv[i-1]*inv[i]%p;
17     }
18 }
19 
20 int C(int n,int m)
21 {
22     if (m>n) return 0;
23     return fac[n]*facInv[m]%MOD*facInv[n-m]%MOD;
24 }
25 
26 int Lucas(int n,int m)
27 {
28     if (m>n) return 0;
29     long long ans=1;
30     for (; m; n/=MOD,m/=MOD)
31         ans=(ans*C(n%MOD,m%MOD))%MOD;
32     return ans;
33 }
34 
35 int main()
36 {
37     Init(MOD);
38     scanf("%d",&T);
39     while (T--)
40     {
41         scanf("%d%d",&n,&m);
42         printf("%d\n",Lucas(n,m));
43     }
44 }

转载于:https://www.cnblogs.com/refun/p/9237003.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值