题意
给你一个由的全排列组成的序列,问你这个序列里面有多少个
的排列
思路
有两种情况
情况1
这个排列在某一个
排列里面,我们把
当成一个整理,那么方案数为
,接着我们计算
排列的方案,那么这种情况的方案数为
情况2
我们知道一个排列为
其中为最后一个满足
的
那么下一个排列就为,其中
是
右边大于
中的最小值
情况2就是:这个排列在两个
排列之间,这个时候也有两种情况
情况2.1
假设排***认的话,那么
和
都确定了,这个时候就剩下
个未确定
那么方案数就为,但是因为
个里面需要出现一个
号,那么这个情况的方案数就为
情况2.2
首先第二列的左边排列可以随便拍也就是
, 第一列右边
排列在这种情况下也确定了(因为他们只能递减)
接着剩余的里面需要至少一个
号,那么就是排除一种全是
的情况
那么这个情况的方案数为
求解出这些情况后,可以化简方程为
代码
/**
* author: andif
* created: 02.09.2023 17:22:38
**/
#include<bits/stdc++.h>
using namespace std;
#define de(x) cerr << #x << " = " << x << endl
#define dd(x) cerr << #x << " = " << x << " "
#define rep(i, a, b) for(int i = a; i < b; ++i)
#define per(i, a, b) for(int i = a; i > b; --i)
#define mt(a, b) memset(a, b, sizeof(a))
#define sz(a) (int)a.size()
#define fi first
#define se second
#define qc ios_base::sync_with_stdio(0);cin.tie(0)
#define eb emplace_back
#define all(a) a.begin(), a.end()
using ll = long long;
using db = double;
using pii = pair<int, int>;
using pdd = pair<db, db>;
using pll = pair<ll, ll>;
using vi = vector<int>;
const db eps = 1e-9;
const int mod = 1e9 + 7;
const int N = 1e6 + 6;
int qpow(int a, int b) {
int ret = 1;
while(b) {
if (b & 1) {
ret = 1ll * ret * a % mod;
}
a = 1ll * a * a % mod;
b >>= 1;
}
return ret;
}
vi f(N), inv(N), sinv(N);
void init() {
f[0] = 1;
rep(i, 1, N) f[i] = 1ll * f[i - 1] * i % mod;
inv[N - 1] = qpow(f[N - 1], mod - 2);
per(i, N - 2, -1) inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;
sinv[1] = inv[1];
rep(i, 2, N) sinv[i] = (1ll * sinv[i - 1] + inv[i]) % mod;
}
int main() {
qc;
init();
int t; cin >> t;
while(t--) {
int n, m; cin >> n >> m;
int ans = 1ll * f[n - m + 1] * f[m] % mod;
ans = (ans + 1ll * f[n - m] * f[m] % mod * (m - 1) % mod) % mod;
ans = (ans - 1ll * f[m] * sinv[m - 1] % mod + mod) % mod;
cout << ans << '\n';
}
return 0;
}