[关闭]
@wsndy-xx 2018-06-19T14:50:01.000000Z 字数 1277 阅读 763

Luogu 2480 古代猪文

题解


question


由费马小定理

先求质数部分, 记
得同余方程组

定理求
合并

Code

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int mod = 999911659, MOD = 999911658;
  5. int n, g, num[4], prime[4] = {2, 3, 4679, 35617}, fact[40000] = {1};
  6. int qpow(ll a, int b, int p) {
  7. int ans = 1;
  8. for (; b; a = a * a % p, b >>= 1) {
  9. if (b & 1) {
  10. ans = ans * a % p;
  11. }
  12. }
  13. return ans;
  14. }
  15. int C(int n, int m, int p) {
  16. if (n < m) return 0;
  17. return fact[n] * qpow(fact[n - m] * fact[m], p - 2, p) % p;
  18. }
  19. int lucas(int n, int m, int p) {
  20. if (m == 0) return 1;
  21. return C(n % p, m % p, p) * lucas(n / p, m / p, p) % p;
  22. }
  23. int crt() {
  24. int ans = 0;
  25. for (int i = 0; i < 4; i++) {
  26. int tmp = MOD / prime[i];
  27. ans = (ans + 1LL * num[i] * tmp % MOD * qpow(tmp, prime[i] - 2, prime[i]) % MOD) % MOD;
  28. }
  29. return ans;
  30. }
  31. int main() {
  32. scanf("%d %d", &n, &g);
  33. if (g == mod) {
  34. printf("0\n");
  35. return 0;
  36. }
  37. for (int i = 0; i < 4; i++) {
  38. fact[0] = 1;
  39. for (int j = 1; j <= prime[i]; j++) {
  40. fact[j] = fact[j - 1] * j % prime[i];
  41. }
  42. for (int d = 1; d * d <= n; d++) {
  43. if (n % d != 0) continue;
  44. num[i] = (num[i] + lucas(n, d, prime[i])) % prime[i];
  45. if (n / d == d) continue;
  46. num[i] = (num[i] + lucas(n, n / d, prime[i])) % prime[i];
  47. }
  48. }
  49. printf("%d\n", qpow(g, crt(), mod));
  50. return 0;
  51. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注