[P2480]古代豚羅区温家宝

タイトル効果:シーク
\ [G ^ {\和\ limits_ {D | N} \ binom {n}は{K}} MOD \ \ 999911659 \]

ソリューション:ルーカス定理中国剰余定理+

ルーカスインデックスは次いで、4つの解に中国の剰余定理を使用して結合、モールド素数の各溶液及びタイプの定理を用いて計算しました。

列挙過程でNの因子、直接中国の剰余定理、同じ答えを合成された4つの解の計算であってもよいです。

コードは以下の通りです

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const LL mod = 999911658;
const LL md[] = {2, 3, 4679, 35617};
const int maxn = 40000;
LL fac[maxn];

inline LL fpow(LL a, LL b, LL c) {
    LL ret = 1 % c;
    for (; b; b >>= 1, a = a * a % c) {
        if (b & 1) {
            ret = ret * a % c;
        }
    }
    return ret;
}
inline LL comb(LL x, LL y, LL p) {
    if (y > x) {
        return 0;
    }
    return fac[x] * fpow(fac[x - y], p - 2, p) % p * fpow(fac[y], p - 2, p) % p;
}
LL Lucas(LL x, LL y, LL p) {
    if (y == 0) {
        return 1;
    }
    return Lucas(x / p, y / p, p) * comb(x % p, y % p, p) % p;
}
LL CRT(vector<LL> &v) {
    LL ret = 0;
    for (int i = 0; i < 4; i++) {
        ret = (ret + mod / md[i] * fpow(mod / md[i], md[i] - 2, md[i]) % mod * v[i] % mod) % mod;
    }
    return ret;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    LL n, G;
    cin >> n >> G;
    if (G % (mod + 1) == 0) {
        cout << 0 << endl;
        return 0;
    }
    vector<LL> v;
    for (int i = 0; i < 4; i++) {
        LL res = 0;
        fac[0] = 1;
        for (int j = 1; j < 35617; j++) {
            fac[j] = fac[j - 1] * j % md[i];
        }
        for (int j = 1; j <= sqrt(n); j++) {
            if (n % j == 0) {
                res = (res + Lucas(n, n / j, md[i])) % md[i];
                if (j * j != n) {
                    res = (res + Lucas(n, j, md[i])) % md[i];
                }
            }
        }
        v.push_back(res);
    }
    LL p = CRT(v);
    cout << fpow(G, p, mod + 1) << endl;
    return 0;
}
/*
2
3
4679
35617
*/

おすすめ

転載: www.cnblogs.com/wzj-xhjbk/p/11647360.html