dls的数论-Lucas定理及扩展

Lucas定理





#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 1e6+10;
int fac[N], inv[N];
LL p, T;
LL qmi(LL a, LL b, LL mod){
    LL res = 1 % mod;
    while(b){
        if(b&1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

LL C(LL a, LL b){
    if(b < 0 || b > a) return 0;
    return (LL)fac[a] * inv[b] % p * inv[a - b] % p;
}

int main(){
    scanf("%lld%lld", &p, &T);
    fac[0] = 1;
    for(int i = 1; i <= p - 1; i ++) fac[i] = (LL)fac[i - 1] * i % p;
    inv[p - 1] = qmi(fac[p - 1], p - 2, p);
    for(int i = p - 2; i >= 0; i --) inv[i] = (LL)inv[i + 1] * (i + 1) % p;
    while(T--){
        LL n, m; scanf("%lld%lld", &n, &m);
        LL ans = 1;
        while( n > 0 || m > 0){
            ans = ans * C(n % p, m % p) % p;
            n /= p; m /= p;
        }
        printf("%lld\n", ans);
    }    
    return 0;
}

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 1e6+10;
typedef pair<int, int> PII;
PII pq[N];
LL A[N], B[N], ans[N];
int fac[N], phipe, pr[N];

LL qmi(LL a, LL b, LL mod){
    LL res = 1 % mod;
    while(b){
        if(b&1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

LL cntp, cnts;
LL calc(LL a, LL p, LL pe, int w){
    LL val = 1;
    while(a){
        cntp += a / p * w;
        cnts += a / pe * w;
        val = val * fac[a % pe] % pe;
        a /= p;
    }
    return val;
}

LL C(LL a, LL b, LL p, LL pe){
    cntp = 0, cnts = 0;
    auto f1 = calc(a, p, pe, 1);
    auto f2 = calc(b, p, pe, -1);
    auto f3 = calc(a - b, p, pe, -1);
    LL v1 = f1 * qmi(f2 * f3 % pe, phipe - 1, pe) % pe;
    LL v2 = qmi(p, cntp, pe);
    LL v3 = qmi(fac[pe], cnts, pe);
    return v1 * v2 % pe * v3 % pe; 
}

int main(){
    int q, T;
    scanf("%d %d", &q, &T);
    
    int M = q, t = 0;
    for(int i = 2; i <= q; i ++){
        if(q % i == 0){
            int pe = 1;
            while(q % i == 0) q /= i, pe *= i;
            pq[t ++] = {i, pe}; 
        }
    }
 
    for(int i = 0; i < t; i ++){
        int pe = pq[i].second;
        for(int j = 0; j < M; j ++){
            if(j % pe == 1 && j % (M / pe) == 0){
                pr[i] = j;
                break;
            }
        }
    }

    for(int i = 0; i < T; i ++) scanf("%lld %lld", &A[i], &B[i]);

    for(int i = 0; i < t; i ++){
        int p = pq[i].first, pe = pq[i].second;
        fac[0] = 1;
        for(int j = 1; j <= pe; j ++){
            if(j % p == 0) fac[j] = fac[j - 1];
            else fac[j] = (LL)fac[j - 1] * j % pe;
        }
        phipe = (LL)pe * (p - 1) / p;

        for(int j = 0; j < T; j ++){
            ans[j] = (ans[j] + C(A[j], B[j], p, pe) * pr[i] % M) % M;
        }
    }

    for(int j = 0; j < T; j ++) printf("%lld\n", ans[j]);

    return 0;
}




#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 1e6+10;
int n, G, pr[N];
PII pq[N];
int A[N], B[N], fac[N], phipe;
LL ans;

LL qmi(LL a, LL b, LL mod){
    LL res = 1 % mod;
    while(b){
        if(b&1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

LL cntp, cnts;
LL calc(LL a, LL p, LL pe, int w){
    LL val = 1;
    while(a){
        cntp += a / p * w;
        cnts += a / pe * w;
        val = val * fac[a % pe] % pe;
        a /= p;
    }
    return val;
}

LL C(LL a, LL b, LL p, LL pe){
    cntp = 0, cnts = 0;
    LL f1 = calc(a, p, pe, 1);
    LL f2 = calc(b, p, pe, -1);
    LL f3 = calc(a - b, p, pe, -1);
    LL v1 = f1 * qmi(f2 * f3 % pe, phipe - 1, pe) % pe;
    LL v2 = qmi(p, cntp, pe);
    LL v3 = qmi(fac[pe], cnts, pe);
    return v1 * v2 % pe * v3 % pe;
}

int main(){
    scanf("%d %d", &n, &G);
    if(G % 999911659 == 0){
        puts("0");
        return 0;
    }
    int M = 999911659 - 1, t = 0;
    int m = M;
    for(int i = 2; i <= m; i ++){
        if(m % i == 0){
            int pe = 1;
            while(m % i == 0) m /= i, pe *= i;
            pq[t ++] = {i, pe};
        }
    }

    for(int i = 0; i < t; i ++){
        int pe = pq[i].second;
        int Mi = M / pe;
        for(int j = 0; j < M; j += Mi){
            if(j % pe == 1){
                pr[i] = j; break;
            }
        }
    }

    int T = 0;
    for(int i = 1; i <= n / i; i ++){
        if(n % i == 0){
            A[T] = n, B[T ++] = i;
            if(n / i != i) A[T] = n, B[T ++] = n / i;
        }
    }

    for(int i = 0; i < t; i ++){
        int p = pq[i].first, pe = pq[i].second;
        fac[0] = 1;
        for(int j = 1; j <= pe; j ++){
            if(j % p == 0) fac[j] = fac[j - 1];
            else fac[j] = (LL) fac[j - 1] * j % pe;
        }
        phipe = (LL)pe * (p - 1) / p;
        for(int j = 0; j < T; j ++){
            ans = ( ans + (LL)C(A[j], B[j], p, pe) * pr[i] % M ) % M;
        }
    }
    printf("%lld\n", qmi(G, ans, 999911659));

    return 0;
}

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 1e6+10;
int n, G, pr[N];
PII pq[N];
int fac[N], phipe;
PII A[N];
int T;
LL ans;

LL qmi(LL a, LL b, LL mod){
    LL res = 1 % mod;
    while(b){
        if(b&1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

LL cntp, cnts;
LL calc(LL a, LL p, LL pe, int w){
    LL val = 1;
    while(a){
        cntp += a / p * w;
        cnts += a / pe * w;
        val = val * fac[a % pe] % pe;
        a /= p;
    }
    return val;
}

LL C(LL p, LL pe){
    cntp = 0, cnts = 0;
    LL v1 = 1;
    for(int i = 0; i < T; i ++){
        LL f = calc(A[i].first, p, pe, A[i].second);
        v1 = v1 * qmi(f, phipe + A[i].second, pe) % pe;
    }
    LL v2 = qmi(p, cntp, pe);
    LL v3 = qmi(fac[pe],  cnts, pe);
    return v1 * v2 % pe * v3 % pe;
}

int main(){
    int m; scanf("%d", &m);
    int M = m;
    int t = 0;
    for(int i = 2; i <= m; i ++){
        if(m % i == 0){
            int pe = 1;
            while(m % i == 0) m /= i, pe *= i;
            pq[t ++] = {i, pe};
        }
    }

    for(int i = 0; i < t; i ++){
        int pe = pq[i].second;
        int Mi = M / pe;
        for(int j = 0; j < M; j += Mi){
            if(j % pe == 1){
                pr[i] = j; break;
            }
        }
    }

    
    int s, cnt2; scanf("%d %d", &s, &T);
    T ++; A[0] = {s, 1};
    for(int i = 1; i < T; i ++){
        int a; scanf("%d", &a);
        A[i] = {a, -1};
        s -= a;
    }
    if(s < 0){
        puts("Impossible");
        return 0;
    }
    if(s > 0) A[T ++] = {s, -1};

    for(int i = 0; i < t; i ++){
        int p = pq[i].first, pe = pq[i].second;
        fac[0] = 1;
        for(int j = 1; j <= pe; j ++){
            if(j % p == 0) fac[j] = fac[j - 1];
            else fac[j] = (LL) fac[j - 1] * j % pe;
        }
        phipe = (LL)pe * (p - 1) / p;
        ans += C(p, pe) * pr[i];
        ans %= M;
    }
    printf("%lld\n", ans);

    return 0;
}

posted @ 2022-03-30 15:22  牛佳文  阅读(34)  评论(0编辑  收藏  举报