P4071 [SDOI2016]排列計數
阿新 • • 發佈:2020-07-23
題目描述
求有多少種11到nn的排列aa,滿足序列恰好有mm個位置ii,使得a_i = iai=i。
答案對10^9 + 7109+7取模。
輸入格式
本題單測試點內有多組資料。
輸入的第一行是一個整數TT,代表測試資料的整數。
以下TT行,每行描述一組測試資料。
對於每組測試資料,每行輸入兩個整數,依次代表nn和mm。
輸出格式
共輸出TT行,對於每組測試資料,輸出一行一個整數代表答案。
輸入輸出樣例
輸入 #15 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; }