1. 程式人生 > >ACM數論模版

ACM數論模版

#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; }