递推公式
求解C(n, m)%p
费马小定理的转换
线性求inv和fac
#include<bits/stdc++.h>
#define ll long long
#define asd cout<<"!"<<endl
using namespace std;
const ll maxn=1e6+10;//memory:20068KB!!
const ll p=1e9+7;
ll fac[maxn];
ll inv[maxn];
int a[maxn];
void fac_init()
{
fac[0]=fac[1]=1;//both 0 1 initiate
for (int i=1;i<maxn;i++) fac[i]=(fac[i-1]*(i%p))%p;
inv[0]=inv[1]=1;
for(int i=2;i<maxn;i++) inv[i]=(p-p/i)*inv[p%i]%p;
for(int i=2;i<maxn;i++) inv[i]=inv[i]*inv[i-1]%p;//little trick
}
ll C(int i,int j)
{
return fac[i]*inv[i-j]%p*inv[j]%p;
}
int main()
{
fac_init();
int n;
cin>>n;
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
a[0]=1000,a[n+1]=1;
ll l=0;
ll ans=1;
for (int i=1;i<=n+1;i++) if (a[i])
{
if (a[l]<a[i]) break;
ans=ans*C(a[l]-a[i]+i-l-1,i-l-1);//little trick?
ans%=p;
l=i;//little trick
}
cout<<ans;
}
拓展欧几里得
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=2000+10;
const ll MAX=200+10;
const ll p=1e9+7;
ll fac[maxn];//n!
ll inv[maxn];//(n!)^(-1)
ll c[maxn][maxn];
void Exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) x = 1, y = 0;
else Exgcd(b, a % b, y, x), y -= a / b * x;
}
void fac_init()
{
fac[0]=1;
for (ll i=1;i<=MAX;i++) fac[i]=(fac[i-1]*(i%p))%p;
}
ll get_inv(ll k)
{
ll x,y;
Exgcd(k,p,x,y);
x=(x%p+p)%p;
return x;
}
int main()
{
fac_init();
ll T;
cin>>T;
while (T--)
{
ll n,m;
cin>>n>>m;
for (ll i=1;i<=MAX;i++)
for (ll j=1;j<=i;j++)
{
c[i][j]=(fac[i]*get_inv((fac[i-j]*fac[j])%p))%p;
}
printf("%lld
",c[n][m]);
}
}
费马小定理和卢卡斯定理//???
搬运:https://xienaoban.github.io/posts/36480
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll p=10007;
ll pow_mod(ll a, ll b, const int &pr)
{
ll ans = 1;
while (b) {
if (b & 1) ans = ans * a % pr;
b >>= 1;
a = a * a % pr;
}
return ans;
}
ll C_small(ll n, ll m, const int &pr)
{
ll ans = 1;
for (int i = 1; i <= m; i++)
{
ll a = (n - m + i) % pr;
ll b = i % pr;
ans = ans * (a * pow_mod(b, pr - 2, pr) % pr) % pr; //Fermat Theory
}
return ans;
}
ll C(ll n, ll m, const int &pr) // Lucas's theorem
{
if (m == 0 || m == n) return 1;
return C_small(n % pr, m % pr, pr) * C(n / pr, m / pr, pr) % pr;
}
int main()
{
ll n,m;
cin>>n>>m;
cout<<C_small(n,m,p)<<endl;
cout<<C(n,m,p)<<endl;
}