Expand Lucas Theorem template Full Notes

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
//#define ll long long
typedef long long ll;
//拓展gcd,求解ax+by=gcd(a,b)
void ex_gcd(ll a, ll b, ll & x, ll &y) {
    if (!b) {
        x = 1; y = 0;
    }
    else {
        ex_gcd(b, a%b, y, x);
        y -= x * (a / b);
    }
}
//求解a关于p的逆元,其中gcd(a,p)==1
ll inverse(ll a, ll p) {
    if (!a)return 0ll;
    ll x, y;
    ex_gcd(a, p, x, y);
    x = (x%p + p) % p;
    return x;
}
//快速幂a^b
ll qpow(ll a, ll b, ll p) {
    ll res = 1;
    while (b) {
        if (b & 1)res = res * a%p;
        a = a * a%p;
        b >>= 1;
    }
    return res;
}
//中国剩余定理,求解x=a[i]%m[i]方程组
ll CRT(int n-, LL * A, LL * m) { 
    LL M = . 1 , RES = 0 ;
     for ( int I = 0 ; I <n-; I ++) M = M * m [I];
     for ( int I = 0 ; I <n-; I ++ ) { 
        LL X, Y; 
        LL (TM) = m / m [I]; 
        ex_gcd ((TM), m [I], X, Y); 
        RES = (RES + (TM) * X * A [I]% M)% M; 
    } 
    return (RES + M)% M; 
} 
// X represents a prime number, P is an exploded T ^ X
 // Calc computing n! % P, P is not necessarily a prime number, the complexity of the P * log (x) (n )
Calc LL (n-LL, LL x, P LL) {
     IF (! n-) return  1 ; 
    LL S = 1 ;
     // calculate P x in the product is not a multiple of 1 to a linear time
     // Since P is not a prime number, can not be with Wilson's Theorem
     // If a plurality of sets, where optimization can play table in advance, but it seems not very convenient, P Total too much 
    for (LL = I 2 ; I <= P; I ++ ) {
         IF (% I X) = S % I * S P; 
    } 
    S = qpow (S, n-/ P, P); // number P on the front part of the following loop
     // this is unnecessary calculation, i.e. the remaining n% P 
    for (LL = I 2 ; I <= n-% P; I ++ )
         IF (X I%) S = S * I% P;
    return S * Calc (n-/ X, X, P)% P; 
} 
// X represents a prime number, P is decomposed X ^ T
 // calculate C (n, m)% P , P is a power of a prime number 
ll multilucas (n-LL, LL m, x LL, LL P) { 
    LL CNT = 0 ;
     // following index numbers respectively containing three factorial complexity x log in
     // this does not know if one can find n! % p of relevant properties 
    for (Register LL I = n-; I> 0 ; I / = X) 
        CNT + = I / X;
     for (LL I = m; I> 0 ; I / = X) CNT - = I / X;
     for (I = n-LL - m; I> 0 ; I / = X) CNT - = I / X;
     returnqpow (x, cnt, P) % P * calc (n, x, P)% P * inverse (calc (m, x, P), P)% P * inverse (calc (n - m, x, P) , P)% P; 
} 
// Solution C (n, m)% P final answer 
LL ex_lucas (n-LL, LL m, LL P) { 
    LL CNT = 0 ;
     // a storage array C (n, m) the results after each prime factor decomposition of the remainder
     // because each germplasm t th factor are relatively prime, it can be solved with a CRT
     // P array stored answer after each class prime factorization of 
    ll P [ 20 is ], A [ 20 is ]; // up prime factorization of 20 
    for (LL I = 2 ; I * I <= P; I ++ ) {
         // play prime number table in advance may be optimized point 
        IF (P% I = = 0 ) { 
            P [CNT] =1;
            while (P%i == 0) { p[cnt] = p[cnt] * i; P /= i; }
            a[cnt] = multilucas(n, m, i, p[cnt]);
            cnt++;
        }
    }
    //最后是一个质数
    if (P > 1)p[cnt] = P, a[cnt++] = multilucas(n, m, P, P);
    return CRT(cnt, a, p);
}
int main()
{
    ll n, m, p;
    scanf("%lld%lld%lld", &n, &m, &p);
    printf("%lld\n", ex_lucas(n, m, p));
    cin >> n;
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/gzr2018/p/11607182.html