社区讨论

30pts 求调

P4071[SDOI2016] 排列计数参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mjveh5mc
此快照首次捕获于
2026/01/01 20:07
2 个月前
此快照最后确认于
2026/01/04 10:25
2 个月前
查看原帖
Subtask1 过了的喵。
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int mod = 1e9 + 7;
const int maxn = 1e6;
int n, m, dp[maxn + 5], fac[maxn + 5], ifac[maxn + 5];

inline int quickPow(int x, int p) {
    int ret = 1;
    for (; p; p >>= 1) {
        if (p & 1) {
            ret = ret * x % mod;
        }
        x = x * x % mod;
    }
    return ret;
}

inline int combine(int n, int m) {
    if (n < 0 || m < 0 || n < m) {
        return 0;
    }
    return fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}
 
void prepare() {
    dp[0] = dp[2] = 1;
    for (int i = 3; i <= maxn; i++) {
        dp[i] = (i - 1) * dp[i - 1] % mod + (i - 1) * dp[i - 2] % mod;
    }
    fac[0] = 1;
    for (int i = 1; i <= maxn; i++) {
        fac[i] = fac[i - 1] * i % mod;
    }
    ifac[maxn] = quickPow(fac[maxn], mod - 2);
    for (int i = maxn - 1; i >= 1; i--) {
        ifac[i] = ifac[i + 1] * (i + 1) % mod;
    }
}

void calculate() {
    scanf ("%lld %lld", &n, &m);
    if (n == 0) {
        printf ("0\n");
        return;
    }
    if (m == 0) {
        printf ("%lld\n", dp[n]);
        return;
    }
    if (n == m) {
        printf ("1\n");
        return;
    }
    if (n - 1 == m) {
        printf ("0\n");
        return;
    }
    printf ("%lld\n", combine(n, m) * dp[n - m] % mod);
}

void work() {
    int T;
    scanf ("%lld", &T);
    prepare();
    while (T--) {
        calculate();
    }
}

signed main() {
    work();
    return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...