1 条题解

  • 0
    @ 2026-10-27 13:20:35

    思路与算法

    所需指数P=Σd|N C(N,d),只需P模q−1,q=999911659为素数。q−1=2·3·4679·35617,先枚举N约数,对这四个素数分别用Lucas计算各组合数之和,再CRT合成P模q−1,最后模快速幂。若G被q整除,由P≥1直接输出0。

    正确性说明

    每种保留文字数d对应C(N,d)种选择,约数取遍全部可能,故指数公式正确。Lucas把每个组合数对素数的余数拆为数位组合数积;四个素因子互质,CRT唯一恢复指数模q−1。G不被素数q整除时费马小定理允许指数按q−1约简;整除时正指数必为0。两种情形覆盖全部输入。

    复杂度

    约数枚举O(sqrt N),四个素数阶乘及逆阶乘初始化O(Σp),每个约数组合数O(Σlog_p N),模幂O(log q)。总O(sqrt N+Σp+τ(N)Σlog_p N),空间O(max p+τ(N))。

    易错点

    模数统一为999911659,描述中尾随4是已公开纠正的笔误。指数取模q−1而非q;大组合数不能用普通阶乘除法。G%q0必须先处理,不能把正指数约为0后错误算成1。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    const ll MOD = 999911659, PHI = MOD - 1;
    ll power(ll a, ll n, ll p) {
        ll r = 1;
        for (a %= p; n; n >>= 1, a = a * a % p)
            if (n & 1)
                r = r * a % p;
        return r;
    }
    int main() {
        ll n, g;
        cin >> n >> g;
        if (g % MOD == 0) {
            cout << 0 << '\n';
            return 0;
        }
        vector<ll> div;
        for (ll d = 1; d * d <= n; d++)
            if (n % d == 0) {
                div.push_back(d);
                if (d * d != n)
                    div.push_back(n / d);
            }
        ll exponent = 0;
        for (int p : {2, 3, 4679, 35617}) {
            vector<ll> f(p, 1), iv(p, 1);
            for (int i = 1; i < p; i++)
                f[i] = f[i - 1] * i % p;
            iv[p - 1] = power(f[p - 1], p - 2, p);
            for (int i = p - 1; i; i--)
                iv[i - 1] = iv[i] * i % p;
            auto C = [&](ll x, ll y) {
                ll z = 1;
                while (x || y) {
                    int a = x % p, b = y % p;
                    if (b > a)
                        return 0LL;
                    z = z * f[a] % p * iv[b] % p * iv[a - b] % p;
                    x /= p;
                    y /= p;
                }
                return z;
            };
            ll rem = 0;
            for (ll d : div)
                rem = (rem + C(n, d)) % p;
            ll part = PHI / p;
            exponent = (exponent + rem * part % PHI * power(part, p - 2, p)) % PHI;
        }
        cout << power(g, exponent, MOD) << '\n';
    }
    
    • 1

    信息

    ID
    2103
    时间
    1000ms
    内存
    512MiB
    难度
    提高+
    标签
    递交数
    0
    已通过
    0
    上传者