大数C(n,m)模板+素数+素数因子p的指数+快速幂
2018-09-25 本文已影响4人
_弓长_大人
#include <iostream>
#include <vector>
using namespace std;
#define Mod 1000000009
typedef long long ll;
// 计算n以内所有的质数
vector<int> primelessthanN(int n)
{
vector<bool> isprime(n+1, true);
vector<int> prime;
prime.push_back(2);
int i;
for(i=3; i*i<=n; i+=2)
{
if(isprime[i])
{
prime.push_back(i);
for(int j=i*i; j<=n; j+=i)
isprime[j]=false;
}
}
while(i<=n)
{
if(isprime[i])
prime.push_back(i);
i+=2;
}
return prime;
}
// 计算素数因子p的指数
int Cal(int n, int p)
{
int res=0;
ll rec=p;
while((ll)n>=rec)
{
res+=(int)((ll)n/rec);
rec*=(ll)p;
}
return res;
}
// 计算n^k对Mod取余
ll PowerMod(int n, int k)
{
int t(k),n0(n);
ll res=(ll)1;
while(t)
{
if(t&1)
res=(res*(ll)n0)%Mod;
n0=(n0*n0)%Mod;
t>>=1;
}
return res;
}
// 计算C(n,m),即原式的C(n+m,m)
ll Cnm(int n, int m)
{
vector<int> prime=primelessthanN(n);
ll res=1;
for(int i=0; i<prime.size(); i++)
{
res=(res*(PowerMod(prime[i],Cal(n,prime[i])-Cal(n-m,prime[i])-Cal(m,prime[i]))))%Mod;
}
return res;
}
// main函数
int main()
{
int n,m;
int t;
cin>>t;
while(t--)
{
cin >> n >> m;
int nn=max(n,m);
int mm=min(n,m);
cout << Cnm(nn,mm) << endl;
}
//system("pause");
return 0;
}