刚开始干了一个预处理阶乘逆元的代码连样例都没过,调试发现预处理的 P 之后的阶乘都是 0 了。所以预处理阶乘逆元就会因此而错误?
那么预处理阶乘逆元的方法是在 P 为质数且n<P 的情况下才适用吗?
以下为部分调试信息:
jc[i]、i
1 1
2 2
1 3
4 4
0 5
0 6
0 7
0 8
0 9
0 10
以下为我的预处理阶乘逆元代码:
#include <iostream>
#define GMY (520&1314)
#define char_phi signed
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define re register int
#define DMARK cerr << "###"
#define _ ' '
#define Endl cout << '\n'
#define Dl cerr << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define mod %
#define N 100005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}
/*
复习lucas是吧
Lucas(x, y, P) = Lucas(x/P, y/P, P) * C(x%P, y%P) % P
*/
int T;
long long n, m, P;
long long jc[N], ny[N];
inline long long ksm(long long A, long long B){
long long res(1);
while (B != 0){
if ((B & 1) == 1) res = res * A mod P;
A = A * A mod P;
B >>= 1;
}
return res;
}
inline long long C(long long x, long long y){ return jc[x] * ny[y] mod P * ny[x-y] mod P; }
long long lucas(long long x, long long y, long long P){
if (y == 0)
return 1;
return (lucas(x/P, y/P, P) * C(x mod P, y mod P) mod P);
}
inline void work(){
cin >> n >> m >> P;
jc[0] = 1;
for (long long i = 1 ; i <= N-5 ; ++ i)
jc[i] = jc[i-1] * i mod P;// cout << jc[i] << _ << jc[i-1] << _ << i << '\n';
// DMARK;
ny[N-5] = ksm(jc[N-5], P-2);
for (long long i = N-5-1 ; i >= 0 ; -- i)
ny[i] = ny[i+1] * (i+1) mod P;
// cerr << jc[1024] << _ << ny[1024] << '\n';
cout << lucas(n+m, n, P) << '\n';
}
// #define IXINGMY
char_phi main(){
#ifdef IXINGMY
FBI_OPENTHEDOOR(a, a);
#endif
Fastio_setup();
cin >> T;
while (T --)
work();
return GMY;
}
感谢各位大佬解答!