#include <iostream> #include <cstdio> #include <algorithm> using namespace std; #define ll long long #define NV 1000005 复杂度(log n),表示a关于取摸n的逆元, 要求 a,n互质 */ ll extend_gcd(ll a, ll b, ll &x, ll &y) { if (b == 0) { x = 1, y = 0; return a; } else{ ll r = extend_gcd(b, a % b, y, x); y -= x * (a / b); return r; } } ll mod_inverse(ll a, ll n) { ll x, y; extend_gcd(a, n, x, y); x = (x % n + n) % n; return x; } ll fact[NV],n,p,e,k; ll mod_fact(ll n, ll p ,ll & e){ e = 0; if(n == 0) return 1; ll res = mod_fact(n / p , p ,e); e += n / p; if(n / p % 2 != 0)return res * (p - fact[n % p]) % p; return res * fact[n % p] % p; } ll mod_comb(ll n , ll k , ll p){ if(n < 0 || k < 0 || n < k )return 0; ll e1 ,e2 , e3; ll a1 = mod_fact(n ,p ,e1) , a2 = mod_fact(k , p , e2) , a3 = mod_fact( n-k , p ,e3 ); if( e1 > e2 +e3 )return 0 ; return a1 * mod_inverse(a2 * a3 % p ,p) % p; } void init(){ ll tmp=1;fact[0]=1; for(int i=1 ; i< p ; i++){ tmp =tmp * i; fact[i] = tmp % p; } } int main(){ cout<<"n!=a*p^e"<<endl; cout<<"p is a prime number , puts in n , p (1-100005) ,in order"<<endl; cout<<"return a%p"<<endl; cin>>n>>p; init(); for(int i=0 ; i<p ;i++) printf("%I64d%c",fact[i],i==p-1 ? '\n':' '); cout<<"a%p = "<<mod_fact(n,p,e)<<endl; cout<<"e = "<<e<<endl;puts("_______________________________________"); cout<<"C n k mod p |n个数取k个的组合数 % p"<<endl; cout<<"p is a prime number gets n , k, p in order "<<endl; cin>>n>>k>>p;init(); cout<<mod_comb(n,k,p)<<endl; return 0; }
|