P4071 [SDOI2016]排列计数
题目描述
求有多少种 11 到 nn 的排列 aa,满足序列恰好有 mm 个位置 ii,使得 a_i = iai=i。
答案对 10^9 + 7109+7 取模。
输入格式
本题单测试点内有多组数据。
输入的第一行是一个整数 TT,代表测试数据的整数。
以下 TT 行,每行描述一组测试数据。
对于每组测试数据,每行输入两个整数,依次代表 nn 和 mm。
输出格式
共输出 TT 行,对于每组测试数据,输出一行一个整数代表答案。
输入输出样例
输入 #1
5 1 0 1 1 5 2 100 50 10000 5000
输出 #1
0 1 20 578028887 60695423
说明/提示
数据规模与约定
本题共 20 个测试点,各测试点等分,其数据规模如下表。
| 测试点编号 | T =T= | n, m \leqn,m≤ | 测试点编号 | T =T= | n, m \leqn,m≤ |
|---|---|---|---|---|---|
| 1\sim 31∼3 | 10^3103 | 88 | 10 \sim 1210∼12 | 10^3103 | 10^3103 |
| 4 \sim 64∼6 | 10^3103 | 1212 | 13 \sim 1413∼14 | 5 \times 10^55×105 | 10^3103 |
| 7 \sim 97∼9 | 10^3103 | 100100 | 15 \sim 2015∼20 | 5 \times 10^55×105 | 10^6106 |
对于全部的测试点,保证 1 \leq T \leq 5 \times 10^51≤T≤5×105,1 \leq n \leq 10^61≤n≤106,0 \leq m \leq 10^60≤m≤106。
// 错排模板题,f[i]为错排 #include<bits/stdc++.h> using namespace std; const int MAXN = 1e6 + 7; typedef long long LL; const LL MOD = 1e9 + 7; LL f[MAXN], fac[MAXN]; void init() { f[1] = 0; f[2] = 1; for (int i = 3; i < MAXN; i++) f[i] = (i - 1) * (f[i - 1] + f[i - 2]) % MOD; fac[0] = 1; for (int i = 1; i < MAXN; i++) fac[i] = (fac[i - 1] * i) % MOD; } LL ksm(LL a, LL b) { LL ans = 1; while (b) { if (b & 1) ans = ans * a % MOD; a = a * a % MOD; b >>= 1; } return ans; } LL inv(LL a) { return ksm(a, MOD - 2); } int main() { init(); int T, n, m; cin >> T; init(); while (T--) { scanf("%d%d", &n, &m); if (n == m) { printf("1\n"); continue; } LL ans = fac[n] * inv(fac[m]) % MOD * inv(fac[n - m]) % MOD * f[n - m] % MOD; printf("%lld\n", ans); } return 0; }

浙公网安备 33010602011771号