P2155 [SDOI2008]沙拉公主的困惑
P2155 SDOI2008沙拉公主的困惑
我们显然可以知道,本题是求 \(\displaystyle \sum_{i=1}^{N!}[\gcd(i, M!) =1]\)
那么我们 莫比乌斯反演 可以分块求一下。
\[\frac{N!}{M!} \cdot M! \prod_{\tiny \begin{matrix}p\in prime\\p \mid M!\end{matrix}} \frac{p-1}{p} = N! \prod_{\tiny \begin{matrix}p\in prime\\p \mid M!\end{matrix}} \frac{p-1}{p}
\]
看出这是个欧拉函数,然而多组询问,那么我们预处理一下。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll MAXN = 1e7+10;
ll T, R, N, M, cnt, ans[MAXN], prime[MAXN], inv[MAXN], fac[MAXN];
bool vis[MAXN];
void ini();
int main() {
ios::sync_with_stdio(false);
cin >> T >> R;
ini();
while (T--) {
cin >> N >> M;
printf("%lld\n", fac[N] * ans[M] % R);
}
return 0;
}
void ini() {
fac[1] = 1, fac[0] = 1, inv[1] = 1, inv[0] = 1, ans[0] = 1, ans[1] = 1;
for (ll i = 2; i <= MAXN - 10; i++) {
if (!vis[i]) prime[++cnt] = i;
for (ll j = 1; j <= cnt && prime[j] * i <= MAXN - 10; j++) {
vis[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
}
}
for (ll i = 2; i <= MAXN - 10; i++) inv[i] = inv[R % i] * (R - R / i) % R, fac[i] = fac[i-1] * i % R;
for (ll i = 2; i <= MAXN - 10; i++) {
ans[i] = ans[i-1];
if (!vis[i]) ans[i] = ans[i] * (i-1) % R * inv[i] % R;
}
}
希望我们都有一个光明的未来