蒟蒻刚学OI一秒,就预处理阶乘逆元适用范围求助
查看原帖
蒟蒻刚学OI一秒,就预处理阶乘逆元适用范围求助
652982
char_phi楼主2022/10/13 15:04

刚开始干了一个预处理阶乘逆元的代码连样例都没过,调试发现预处理的 PP 之后的阶乘都是 00 了。所以预处理阶乘逆元就会因此而错误?

那么预处理阶乘逆元的方法是在 PP 为质数且n<Pn < 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;
}

感谢各位大佬解答!

2022/10/13 15:04
加载中...