排列组合+逆元模板
运用费马小定理
#include<stack> #include<queue> #include<map> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define fi first #define se second using namespace std; typedef long long ll; const int maxn=2e5+5; const int mod=1e9+7; int v[maxn]; ll ppow(ll a,ll b) { ll ans=1; while(b) { if(b&1) ans=(ans*a)%mod; a=(a*a)%mod; b>>=1; } return ans; } ll solve(ll now,ll num) { ll ans=1; for(ll i=now;i>now-num;--i) ans=(ans*i)%mod; for(ll i=1;i<=num;++i) { ans=(ans*ppow(i,mod-2))%mod; } return ans; } int main() {
printf("%d\n",(ppow(5,mod-2)%mod*4)%mod); //求4/5的逆元 printf("%d\n",solve(9,3)); return 0; }
这一个是常数时间求逆元,参考链接:https://blog.csdn.net/qq_36979930/article/details/81698003
#include <bits/stdc++.h> #define ll long long using namespace std; const ll mod=1e9+7; const int maxn=1e5+7; ll fac[maxn]; ll inv[maxn]; ll C(int m,int n) { if(m>n) return -1; return fac[n]*inv[m]%mod*inv[n-m]%mod; } ll quick_mod(ll a,ll m) { ll tmp=a%mod; ll ans=1; while(m) { if(m&1) ans=ans*tmp%mod; tmp=tmp*tmp%mod; m>>=1; } return ans; } void init() { fac[0]=1; for(int i=1; i<maxn; i++) fac[i]=(fac[i-1]*i)%mod; inv[maxn-1]=quick_mod(fac[maxn-1],mod-2); for(int i=maxn-2; i>=0; i--) inv[i]=(inv[i+1]*(i+1))%mod; } int main() { init(); ll n,m; while(cin>>n>>m) cout << C(m,n) << endl; return 0; }