【洛谷P2480】古代猪文

匿名 (未验证) 提交于 2019-12-03 00:14:01

题目大意:求
\[ G^{\sum\limits_{d|N}\binom{n}{k}} mod\ \ 999911659 \]

题解:卢卡斯定理+中国剩余定理

利用卢卡斯定理求出指数和式对各个素模数的解,再利用中国剩余定理合并四个解即可。

也可以在枚举 N 的因子的过程中,对于计算的四个解直接进行中国剩余定理的合并,答案不变。

代码如下

#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 */
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!