FZUoj 2020 组合 (组合数学&&Lucas定理)

来源:互联网 发布:js中a标签的href路径 编辑:程序博客网 时间:2024/05/16 13:04
 Problem 2020 组合

Accept: 819    Submit: 1951
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

给出组合数C(n,m), 表示从n个元素中选出m个元素的方案数。例如C(5,2) = 10, C(4,2) = 6.可是当n,m比较大的时候,C(n,m)很大!于是xiaobo希望你输出 C(n,m) mod p的值!

 Input

输入数据第一行是一个正整数T,表示数据组数 (T <= 100) 接下来是T组数据,每组数据有3个正整数 n, m, p (1 <= m <= n <= 10^9, m <= 10^4, m < p < 10^9, p是素数)

 Output

对于每组数据,输出一个正整数,表示C(n,m) mod p的结果。

 Sample Input

2
5 2 3
5 2 61

 Sample Output

1
10
#include<stdio.h>#include<string.h>#include<algorithm>#define ll long longusing namespace std;int n,m,p;ll ksm(ll x,ll y)//快速幂 {ll ans=1;while(y){if(y&1)ans=(ans*x)%p;x*=x;x%=p;y>>=1;}return ans%p;}ll C(int n,int m){int i;ll sum1=1,sum2=1;for(i=1;i<=m;i++){sum1=(sum1*(n-i+1))%p;sum2=(sum2*i)%p;}sum1=(sum1*ksm(sum2,p-2))%p;return sum1;}void solve(int n,int m)//Lucas定理 {ll ans=1;while(n&&m&&ans){ans=(ans*C(n%p,m%p))%p;n/=p;m/=p;}printf("%lld\n",ans);}int main(){int t;scanf("%d",&t);while(t--){scanf("%d%d%d",&n,&m,&p);solve(n,m);}return 0;}



0 0
原创粉丝点击