【模版】卢卡斯定理

给定n,m,p

求 (m改为n)

C表示组合数。

一个测试点内包含多组数据。

输入输出格式

输入格式:

第一行一个整数T,表示数据组数

第二行开始共T行,每行三个数n m p,意义如上

输出格式:

共T行,每行一个整数表示答案。

输入输出样例

输入样例#1:
2
1 2 5
2 1 5
输出样例#1:
3
3

Lucas定理是用于处理组合数取模的定理

通常用于解决阶乘无法解决的问题。

 

cm(a,b)=a!*(b!*(a-b)!)^(p-2)mod p

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 long long p,a[1000001];
 7 long long qpow(int x,int m)
 8 {
 9     if (m==0) return 1;
10     long long tmp=qpow(x,m/2);
11     tmp=(tmp*tmp)%p;
12     if (m%2==1) tmp=(tmp*x)%p;
13     return tmp;
14 }
15 long long getc(int n,int m)
16 {
17     if (n<m) return 0;
18     if (m>n-m) m=n-m;
19     return (a[n]*qpow(a[m],p-2))%p*qpow(a[n-m],p-2)%p;
20 }
21 long long lucas(int n,int m)
22 {
23     if (m==0) return 1;
24      return (getc(n%p,m%p)*lucas(n/p,m/p)%p);
25 }
26 int main()
27 {int n,m,T;
28 int l,i;
29     cin>>T;
30     for (l=1;l<=T;l++)
31     {
32         scanf("%d%d%d",&n,&m,&p);
33         a[0]=1;
34         for (i=1;i<=p;i++)
35         a[i]=(a[i-1]*i)%p;
36         printf("%lld\n",lucas(n+m,n));
37     }
38 }
posted @ 2017-07-02 16:57  Z-Y-Y-S  阅读(254)  评论(0编辑  收藏  举报