@wsndy-xx
2018-06-19T06:50:01.000000Z
字数 1277
阅读 971
题解
求
由费马小定理
先求质数部分, 记
得同余方程组
定理求
合并
求
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int mod = 999911659, MOD = 999911658;int n, g, num[4], prime[4] = {2, 3, 4679, 35617}, fact[40000] = {1};int qpow(ll a, int b, int p) {int ans = 1;for (; b; a = a * a % p, b >>= 1) {if (b & 1) {ans = ans * a % p;}}return ans;}int C(int n, int m, int p) {if (n < m) return 0;return fact[n] * qpow(fact[n - m] * fact[m], p - 2, p) % p;}int lucas(int n, int m, int p) {if (m == 0) return 1;return C(n % p, m % p, p) * lucas(n / p, m / p, p) % p;}int crt() {int ans = 0;for (int i = 0; i < 4; i++) {int tmp = MOD / prime[i];ans = (ans + 1LL * num[i] * tmp % MOD * qpow(tmp, prime[i] - 2, prime[i]) % MOD) % MOD;}return ans;}int main() {scanf("%d %d", &n, &g);if (g == mod) {printf("0\n");return 0;}for (int i = 0; i < 4; i++) {fact[0] = 1;for (int j = 1; j <= prime[i]; j++) {fact[j] = fact[j - 1] * j % prime[i];}for (int d = 1; d * d <= n; d++) {if (n % d != 0) continue;num[i] = (num[i] + lucas(n, d, prime[i])) % prime[i];if (n / d == d) continue;num[i] = (num[i] + lucas(n, n / d, prime[i])) % prime[i];}}printf("%d\n", qpow(g, crt(), mod));return 0;}