P2155 [SDOI2008]沙拉公主的困惑

P2155 SDOI2008沙拉公主的困惑
我们显然可以知道,本题是求 (displaystyle sum_{i=1}^{N!}[gcd(i, M!) =1])
那么我们 莫比乌斯反演 可以分块求一下。

[frac{N!}{M!} cdot M! prod_{ iny egin{matrix}pin prime\p mid M!end{matrix}} frac{p-1}{p} = N! prod_{ iny egin{matrix}pin 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
", 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;
    }
}
原文地址:https://www.cnblogs.com/Gensokyo-Alice/p/13719449.html