厌氧代码 × 1
查看原帖
厌氧代码 × 1
749630
wxzzzz楼主2024/8/5 14:20
#include <bits/stdc++.h>
#define ll __int128
using namespace std;
inline ll read() {
    ll x = 0;
    bool f = 1;
    char c = getchar();

    while (c < 48 || c > 57) {
        if (c == '-')
            f = 0;

        c = getchar();
    }

    while (c >= 48 && c <= 57) {
        x = x * 10 + (c ^ 48);
        c = getchar();
    }

    return f ? x : -x;
}
inline void write(ll x) {
    if (x < 0)
        putchar('-'), x = -x;

    if (x > 9)
        write(x / 10);

    putchar(x % 10 + 48);
}
ll qpow(ll x, ll k, ll p) {
    ll ret = 1, base = x;

    while (k) {
        if (k & 1)
            ret = (ret * base) % p;

        base = (base * base) % p;
        k >>= 1;
    }

    return ret;
}
pair<ll, ll> exgcd(ll a, ll b, ll p) {
    if (!b)
        return {1, 0};

    pair<ll, ll> t = exgcd(b, a % b, p);

    ll x = t.first, y = t.second;

    return {y, ((x - a / b * y) % p + p) % p};
}
ll cntf(ll n, ll p) {
    ll ret = 0;

    while (n) {
        ret += n / p;
        n /= p;
    }

    return ret;
}
ll calc(ll n, ll p, ll q) {
    if (!n)
        return 1;

    ll ret = 1, lim = qpow(p, q, 1e18);

    for (ll i = 1; i <= lim; i++)
        if (i % p)
            ret = ret * i % lim;

    ret = qpow(ret, n / lim, lim);

    for (ll i = 1; i <= n % lim; i++)
        if (i % p)
            ret = ret * i % lim;

    ret = ret * calc(n / p, p, q) % lim;
    return ret;
}
ll crt(ll n, ll *a, ll *b) {
    ll p = 1, ret = 0;

    for (ll i = 1; i <= n; i++)
        p *= b[i];

    for (ll i = 1, t; i <= n; i++) {
        t = p / b[i];
        ret = (ret + a[i] * t % p * exgcd(t, b[i], b[i]).first % p) % p;
    }

    return ret;
}
ll nf, a[105], c[105], d[105], fp[105];
ll exlucas(ll n, ll m, ll p) {
    nf = 0;

    for (ll i = 2, tmp = p; tmp > 1; i++) {
        if (tmp % i)
            continue;

        fp[++nf] = i, d[nf] = 1;

        while (!(tmp % i)) {
            tmp /= i;
            c[nf]++, d[nf] *= i;
        }
    }

    for (ll i = 1, x, y, z, t1, t2, t3; i <= nf; i++) {
        x = cntf(n, fp[i]), y = cntf(m, fp[i]), z = cntf(n - m, fp[i]);
        t1 = calc(n, fp[i], c[i]);
        t2 = calc(m, fp[i], c[i]);
        t3 = calc(n - m, fp[i], c[i]);
        a[i] = t1 * exgcd(t2, d[i], d[i]).first % d[i];
        a[i] = a[i] * exgcd(t3, d[i], d[i]).first % d[i];
        a[i] = a[i] * qpow(fp[i], x - y - z, d[i]) % d[i];
    }

    return crt(nf, a, d);
}
int main() {
    ll n = read(), m = read(), p = read();
    write(exlucas(n, m, p));
    return 0;
}

同一份代码AC/WA

2024/8/5 14:20
加载中...