Educational Codeforces Round 83-D. Count the Arrays

7 篇文章 0 订阅
2 篇文章 0 订阅

题目传送门:D. Count the Arrays

在这里插入图片描述
input

3 4

output

6

input

3 5

output

10

input

42 1337

output

806066790

input

100000 200000

output

707899035

样例1解释
题意:给你n,m;
让你构造一个长度为n的数列,要下面满足几个条件
1.保证数列中所有的数都在1~m中,而且有且只有一个数出现过两次,其余数最多只能出现一次。
2.数列中有一个要有这样一个位置i,在i之前的要严格单调增,在i之后的要严格单调递减。俗话说就是要有个尖尖。
问:能构造多少种不同的数列?
思路:
实现我们要从m个数中选出(n-1)个数,(因为有一个数重复)方式有 C ( m , n − 1 ) C(m,n-1) C(m,n1) 表示组合数。然后我们要确定那个重复的数是谁,一共(n-1)个不同的数,因为不能是最大值,所以我们还有(n-2)种情况去选,最后我们已经知道我们选的那个最大值就是那个尖尖,还有两个数和那个最大值的相对位置也固定了,就是一边一个,然后其余的(n-3)个数每个数我们有两种选择,放在那个尖尖的左边还是右边。一共有2(n-3)
所以最后答案就算 a n s = C ( m , n − 1 ) ∗ ( n − 2 ) ∗ 2 ( n − 3 ) ans=C(m,n-1)*(n-2)*2 ^( n^-3^) ans=Cm,n1)(n2)2(n3)
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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值