题目传送门:D. Count the Arrays
input
3 4
output
6
input
3 5
output
10
input
42 1337
output
806066790
input
100000 200000
output
707899035
题意:给你n,m;
让你构造一个长度为n的数列,要下面满足几个条件
1.保证数列中所有的数都在1~m中,而且有且只有一个数出现过两次,其余数最多只能出现一次。
2.数列中有一个要有这样一个位置i,在i之前的要严格单调增,在i之后的要严格单调递减。俗话说就是要有个尖尖。
问:能构造多少种不同的数列?
思路:
实现我们要从m个数中选出(n-1)个数,(因为有一个数重复)方式有
表示组合数。然后我们要确定那个重复的数是谁,一共(n-1)个不同的数,因为不能是最大值,所以我们还有(n-2)种情况去选,最后我们已经知道我们选的那个最大值就是那个尖尖,还有两个数和那个最大值的相对位置也固定了,就是一边一个,然后其余的(n-3)个数每个数我们有两种选择,放在那个尖尖的左边还是右边。一共有2(n-3)种
所以最后答案就算
AC
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<stdlib.h>
#include<queue>
#include<vector>
#include<map>
#include<iostream>
using namespace std;
#define LL long long
#define PI acos(-1.0)
const LL N=2e5+10;
LL mod=998244353;
LL ksm(LL a,LL b)
{
LL ans=1;
while(b)
{
if(b&1)
{
ans*=a;
ans%=mod;
}
a*=a;
a%=mod;
b/=2;
}
return ans;
}
int main()
{
LL n,m;
cin>>n>>m;
if(n==2)
{
cout<<"0"<<endl;
}
else
{
LL as1=1,as2=1;
for(int i=1;i<=n-1;i++)
{
as1=as1*(m-i+1);
as1%=mod;
as2=as2*i;
as2%=mod;
}
cout<<(((as1*ksm(as2,mod-2))%mod*(n-2))%mod*ksm(2,n-3))%mod<<endl;
}
return 0;
}