Count the Arrays CodeForces - 1312D(组合数学)

Your task is to calculate the number of arrays such that:

each array contains n elements;
each element is an integer from 1 to m;
for each array, there is exactly one pair of equal elements;
for each array a, there exists an index i such that the array is strictly ascending before the i-th element and strictly descending after it (formally, it means that aj<aj+1, if j<i, and aj>aj+1, if j≥i).
Input
The first line contains two integers n and m (2≤n≤m≤2⋅105).

Output
Print one integer — the number of arrays that meet all of the aforementioned conditions, taken modulo 998244353.

Examples
Input
3 4
Output
6
Input
3 5
Output
10
Input
42 1337
Output
806066790
Input
100000 200000
Output
707899035
Note
The arrays in the first example are:

[1,2,1];
[1,3,1];
[1,4,1];
[2,3,2];
[2,4,2];
[3,4,3].
思路:数学题总是难倒一大片。
我们按照题目要求的来就可以了。
首先构造一个长度为n-1的严格递增的序列,一共有C(m,n-1)个。
抽取n-2中的任意一个数字,放在严格递增序列的右边。一共有C(m,n-1)*(n-2)个。
在剩下的n-3个数字中,可以在峰值左右两边随意摆放(然后再排序就好了),因此一共是C(m,n-1) *(n-2)*pow(2,n-3).注意一点,就是n=2的时候特判就可以了。
代码如下:
组合数公式用的Lucas定理==。

#include<bits/stdc++.h>
#define LL long long
#define mod 998244353
using namespace std;

LL quick_mod(LL a, LL b,LL p)  
{  
    LL ans = 1;  
    a %= p;  
    while(b)  
    {  
        if(b & 1)  
        {  
            ans = ans * a % p;  
            b--;  
        }  
        b >>= 1;  
        a = a * a % p;  
    }  
    return ans;  
}  
 
LL C(LL n, LL m,LL p)  
{  
    if(m > n) return 0;  
    LL ans = 1;  
    for(int i=1; i<=m; i++)  
    {  
        LL a = (n + i - m) % p;  
        LL b = i % p;  
        ans = ans * (a * quick_mod(b, p-2ll,p) % p) % p;  
    }  
    return ans;  
}  
 
LL Lucas(LL n, LL m,LL p)  
{  
    if(m == 0) return 1;  
    return C(n % p, m % p,p) * Lucas(n / p, m / p,p) % p;  
} 
inline LL qsm(LL x,int y)
{
	LL ans=1;
	while(y)
	{
		if(y&1) ans=(ans*x)%mod;
		y>>=1;
		x=(x*x)%mod;
	}
	return ans%mod;
}

int main()
{
	LL n,m;
	scanf("%lld%lld",&n,&m);
	if(n==2) cout<<0<<endl;
	else cout<<(((Lucas(m,(LL)n-1,mod)*qsm(2LL,n-3))%mod*(LL)(n-2))%mod)<<endl;
}

努力加油a啊,(o)/~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值