2023 年华中科技大学程序设计竞赛新生赛

发布时间 2023-10-24 14:34:06作者: Ke_scholar

2023 年华中科技大学程序设计竞赛新生赛

P9774 [HUSTFC 2023] 新取模运算 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

\(n! \% p\),易知\(1 \sim n \% p\)\(1,2,3\dots p - 1,0,1,2\dots\),所以我们可以预处理出\(1\sim p - 1\)的阶乘,那么答案就是\((p-1)!^{\frac{n}{p}}\times(n\%p)!\),\((n\%p)!\)是计算最后不足\(p\)个的阶乘,若\(n=a\times p=p^b\times x\),还需通过递归计算得出\(x\)

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

long long ksm(long long a, long long b,long long mod) {
	long long res = 1;
	while (b) {
		if (b & 1)res = (res % mod * a % mod) % mod;
		b >>= 1;
		a = (a % mod * a % mod) % mod;
	}
	return res % mod;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int T, p;
	cin >> T >> p;
	vector<i64> fac(p,1);
	for(int i = 2;i < p;i ++)
		fac[i] = fac[i - 1] % p * i % p;

	auto col = [&](auto self, i64 n){
		if(n < p) return fac[n];
		i64 res = 1ll * ksm(fac[p - 1], n / p, p) % p * fac[n % p] % p;
		return res * self(self, n / p) % p;
	};

	while (T --) {
		i64 n;
		cin >> n;
		cout << col(col, n) << '\n';	
	}

	return 0;
}