洛谷 P4071 [SDOI2016] 排列计数 题解

题目描述

求有多少种 \(1\)\(n\) 的排列 \(a\),满足序列恰好有 \(m\) 个位置 \(i\),使得 \(a_i = i\)

答案对 \(10^9 + 7\) 取模。

Slove

分为两个部分

首先,从 \(n\) 个数中选取 \(m\) 个, 作为 \(a_i = i\)

答案为 \(C_n^m\)

其次,对于剩下 \(n - m\) 个,错位排列, 记 \(x\) 个数字的错位排列为 \(D(x)\)

最终答案为 \(C_n^m * D(n - m)\)

由于涉及除法,使用逆元实现组合数

//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
//
//      By txp2024 www.luogu.com.cn  TXP2023 www.github.com
// 
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

#pragma once
#include <vector>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <numeric>
#include <ctype.h>
#include <queue>
#include <cstdarg>
#include <climits>
#include <time.h>
#include <iostream>
#include <stdint.h>

#define _FREAD        true
#define MAX_INF       1e18
#define MAX_NUM_SIZE  35
#define MAXN          (size_t)(1e6)
#define MOD           (size_t)(1e9+7)

typedef long long int ll;
typedef unsigned long long int ull;

inline int64_t fpow(int64_t a, int64_t n, int64_t mod) {
    int64_t base = a, ret = 1;
    while (n) {
        if (n & 1) {
            ret = ret * base;
            ret %= mod;
        }
        base = base * base;
        base %= mod;
        n >>= 1;
    }
    return ret % mod;
}

//快读函数声明
template< typename Type >
inline Type fread(Type* p = nullptr);

//快速输出函数
template<typename Type>
inline void fwrite(Type x);

ll mul[MAXN + 5], inv[MAXN + 5], f[MAXN + 5];
ll t, n, m;

inline void init() {
    mul[0] = 1;
    for (size_t i = 1; i <= MAXN; i++) {
        mul[i] = i * mul[i - 1] % MOD;
    }
    inv[0] = 1;
    inv[MAXN] = fpow(mul[MAXN], MOD - 2, MOD);
    for (size_t i = MAXN - 1; i >= 1; --i) {
        inv[i] = (i + 1) * inv[i + 1] % MOD;
    }
    f[0] = 1;
    f[1] = 0;
    f[2] = 1;
    f[3] = 2;
    for (size_t i = 4; i <= MAXN; i++) {
        f[i] = (i - 1) * (f[i - 1] + f[i - 2]) % MOD;
    }
    return;
}

int main() {

#ifdef _FREOPEN
    freopen("input.txt", "r", stdin);
#endif // _FREOPEN

#ifdef _RUN_TIME
    clock_t start = clock();
#endif // _RUN_TIME

    fread(&t);

    init();
    while (t--) {
		fread(&n), fread(&m);//scanf("%lld%lld",&n,&m);//cin>>n>>m;
        printf("%lld\n", mul[n] * inv[m] % MOD * inv[n - m] % MOD * f[n - m] % MOD);
    }



#ifdef _RUN_TIME
    printf("The running duration is not less than %ld ms\n", clock() - start);
#endif // _RUN_TIME
    return 0;
}

template< typename Type >
inline Type fread(Type* p) {
#if _FREAD
    Type ret = 0, sgn = 0, ch = getchar();
    while (!isdigit(ch)) {
        sgn |= ch == '-', ch = getchar();
    }
    while (isdigit(ch)) ret = ret * 10 + ch - '0', ch = getchar();
    if (p != nullptr) {
        *p = Type(sgn ? -ret : ret);
    }
    return sgn ? -ret : ret;
#else
    if (p == nullptr) {
        Type temp;
        p = &temp;
    }
    scanf("%lld", p);
    return *p;


#endif // _FREAD
}


template<typename Type>
inline void fwrite(Type x) {
    int sta[MAX_NUM_SIZE];
    int top = 0;
    do {
        sta[top++] = x % 10, x /= 10;
    } while (x);
    while (top) {
        putchar(sta[--top] + '0');
    }  // 48 是 '0'
    return;
}



/**
 *              ,----------------,              ,---------,
 *         ,-----------------------,          ,"        ,"|
 *       ,"                      ,"|        ,"        ,"  |
 *      +-----------------------+  |      ,"        ,"    |
 *      |  .-----------------.  |  |     +---------+      |
 *      |  |                 |  |  |     | -==----'|      |
 *      |  |                 |  |  |     |         |      |
 *      |  |  C:\>rp++       |  |  |     |`---=    |      |
 *      |  |                 |  |  |     |==== ooo |      ;
 *      |  |                 |  |  |     |(((( [33]|    ,"
 *      |  `-----------------'  | /      |((((     |  ,"
 *      +-----------------------+/       |         |,"
 *         /_)______________(_/          +---------+
 *    _______________________________
 *   /  oooooooooooooooo  .o.  oooo /,   /-----------
 *  / ==ooooooooooooooo==.o.  ooo= //   /\--{)B     ,"
 * /_==__==========__==_ooo__ooo=_/'   /___________,"
 *
 */
 
posted @ 2025-09-07 21:09  txp2025  阅读(12)  评论(0)    收藏  举报