题目链接
题目大意:让你从(m)个数里面挑出来若干个数构成一个(n)个数的序列,且这个序列有且仅有一对相等的数。并且,这个序列在一个数字之前严格单调递增,在同一个数字之后严格单调递减。问你最多能组成多少个这样的序列。
首先,题目已经告诉我们了,我们要求的序列是一个单峰序列,所以如果(n=2)的话是不能构成这样的序列的(坑点)。
然后我们开始分析,要构成一个含有(n)个数并且有且只有一对数字重复的序列需要(n-1)个数,所以选法一共有(C{{n-1}atop{m}})种,对于这(n-1)个数,因为是单峰的,所以最大的数的位置一定是固定不变的,又要左右两边分别严格单调,所以位置也不能变。所以,能重复出现的数字一共有(n-2)种。最后我们还要考虑左右数字移动的问题。因为相等的数字不能出现在同一边,而且最大的数不能动,所以就只有(n-3)个数可以动,因为这(n-3)个数字都不相同,显然,它们中的任意一个数都能移动到另一边。那么对于(n-3)个数字中的每一个数都有在某一边和不在某一边两种情况,也就是(2^{n-3})种情况。
综上所述,我们的答案就是(C{{n-1}atop{m}} imes (n-2) imes 2^{n-3}),这里组合数比较大,所以我们取模的时候需要用到逆元的知识,然后用快速幂求解即可。
ll qpow(ll x, int y) {
ll res = x, ans = 1;
while(y) {
if (y&1) ans = ans*res%MOD;
res = res*res%MOD;
y >>= 1;
}
return ans;
}
int main(void) {
ll n, m;
while(~scanf("%lld%lld", &n, &m)) {
if (n==2) {
printf("0
");
continue;
}
ll fac1 = 1, fac2 = 1;
for (int i = m; i>m-n+1; --i)
fac1 = fac1*i%MOD;
for (int i = n-1; i>1; --i)
fac2 = fac2*i%MOD;
printf("%lld
", fac1*qpow(fac2, MOD-2)%MOD*(n-2)%MOD*qpow(2, n-3)%MOD);
}
return 0;
}