lucas定理求组合数
定理及其推导由于符号书写不方便,我就写在纸上了(累死)
给定 n 组询问,每组询问给定三个整数 a,b,p,其中 p 是质数,请你输出 C(a,b)modp 的值。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一组 a,b,p。
输出格式
共 n 行,每行输出一个询问的解。
数据范围
1≤n≤20
1≤b≤a≤10^18
1≤p≤10^5
输入样例:
3
5 3 7
3 1 5
6 4 13
输出样例:
3
3
2
#include<bits/stdc++.h> using namespace std; const int N=100002; long long a,b; int p; long long qmi(long long a,long long b,int p) { long long ans=1; while(b) { if(b&1) ans=ans*a%p; a=a*a%p; b>>=1; } return ans; } long long C(long long a,long long b,int p) { if(b>a) return 0; long long ans=1; for(int i=1,j=a;i<=b;i++,j--) { ans=ans*j%p; ans=ans*qmi(i,p-2,p)%p; } return ans; } long long lucas(long long a,long long b,int p) { if(a<p&&b<p) return C(a,b,p); return C(a%p,b%p,p)*lucas(a/p,b/p,p)%p; } int main() { int n; cin>>n; while(n--) { cin>>a>>b>>p; printf("%lld\n",lucas(a,b,p)); } return 0; }
希望大家能够喜欢!
心中所爱,山海可平