ACM數論模版
阿新 • • 發佈:2019-01-22
#include<bits/stdc++.h>
using namespace std;
const int MAXN= 100005;
const int mod = 1e9+7;
typedef long long LL;
LL c[1005][1005];
LL mu[MAXN];
LL euler[MAXN];
int mu[MAXN];
void Mubius()//莫比烏斯函式
{
mu[1]=1;
for(int i=1;i<MAXN;++i)
{
for(int j=i+i;j<MAXN;j+=i)
{
mu[j]-=mu[i];
}
}
}
void extend_gcd(int a, int b, int &x, int &y)//擴充套件歐幾里得
{
if(x==0)
{
a=1;
b=0;
return ;
}
extend_gcd(b, a%b, x, y);
int t=x;
x=y;
y=t-a/b*y;
return ;
}
void comb()//組合數表
{
c[0][0]=1;
for(int i=1; i<1000; ++i)
{
c[i][0]=1;
for(int j=1; j<=i; ++j)
{
c[i][j]=(c[i-1 ][j]+c[i-1][j-1])%mod;
}
}
return ;
}
void euler_t()//直接求尤拉函式值
{
euler[1]=1;
for(int i=2; i<MAXN; ++i)
euler[i]=i;
for(int i=2; i<MAXN; ++i)
{
if(euler[i]==i)
for(int j=i; j<MAXN; j+=i)
{
euler[j]=euler[j]/i*( i-1);
}
}
}
LL quick_pow(LL a, LL b)//快速冪
{
LL res=1;
while(b)
{
if(b&1)
res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
LL Comb(LL a,LL b, LL p)//求組合數
{
if(a < b) return 0;
if(a == b) return 1;
if(b > a-b) b = a-b;
LL ans = 1, ca = 1, cb = 1;
for(LL i=0; i<b; ++i)
{
ca = (ca*(a-i))%p;
cb = (cb*(b-i))%p;
}
ans = (ca*quick_pow(cb, mod-2))%mod;
return ans;
}
LL Lucas(int n, int m, int p)
{
LL ans = 1;
while(n && m && ans)
{
ans = (ans * Comb(n%mod, m%mod, mod))%mod;
n /= mod;
m /= mod;
}
return ans;
}
/*
LL quick_mod(LL a, LL b)
{
LL ans = 1;
a %= p;
while(b)
{
if(b & 1)
{
ans = ans * a % p;
b--;
}
b >>= 1;
a = a * a % p;
}
return ans;
}
LL C(LL n, LL m)
{
if(m > n) return 0;
LL ans = 1;
for(int i=1; i<=m; i++)
{
LL a = (n + i - m) % p;
LL b = i % p;
ans = ans * (a * quick_mod(b, p-2) % p) % p;
}
return ans;
}
LL Lucas(LL n, LL m)
{
if(m == 0) return 1;
return C(n % p, m % p) * Lucas(n / p, m / p) % p;
}
*/
int get_euler(int n)//尤拉函式表
{
int ans=n;
for(int i=2; i*i<=n; ++i)
{
if(n%i==0)
{
ans=ans/i*(i-1);
while(n%i==0)
n/=i;
}
}
if(n!=1)
ans=ans/n*(n-1);
return ans;
}
int main()
{
comb();
euler_t();
LL a, b;
while(~scanf("%lld %lld", &a, &b))
{
printf("%lld\n", Lucas(a, b, mod));
}
return 0;
}