前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CodeForces – 1312D 组合数

CodeForces – 1312D 组合数

作者头像
灯珑LoGin
发布2022-10-31 13:10:06
1870
发布2022-10-31 13:10:06
举报
文章被收录于专栏:龙进的专栏

这题主要就是涉及到满足条件的组合数,

思路:从m个数中选择n-1个不同的数。由于里面的元素只有一个重复,而且重复的元素不能是最大值,那么就要从剩下的n-2个数中选择出一个最大值,下标为i。对于剩下的n-3个数,选x个排在最大值的左侧,这样的话,总共的情况数就是

C(n-1,m)*(n-2)*(2^(n-3))

那么代码就很简单了。但是问题来了,这个组合数会很大,要模除一个数。然后由于同余线性方程组没有除法,因此组合数要取逆元,也就是a^-1=a^(p-2)

求逆元的话就可以用快速幂来求,然后就是看代码了

需要特别注意的是,当n=2的时候,无法满足要求,以及n-1>m的时候,也是无法满足要求的。

代码语言:javascript
复制
#include <iostream>
#include <math.h>
using namespace std;
typedef long long ll;

const ll md = 998244353;
#define MAXN 200010

ll fact[MAXN];

ll qpow(ll x, ll k)
{
    ll ans = 1;
    x %= md;
    while (k)
    {
        if (k & 1)
            ans = (ans * x) % md;

        x = (x * x) % md;
        k >>= 1;
    }
    return ans%md;
}

ll c(ll a, ll b) //C(a,b)
{
    return 1ll*(fact[a] * qpow((fact[b] * fact[a - b]) % md, md - 2)) % md; //模意义下的组合数,分母要取逆元
}

int main()
{
    ll n, m;
    cin >> n >> m;

    if (n == 2 || n - 1 > m)
    {
        cout << 0 << endl;
        return 0;
    }

    fact[0] = 1;
    for (int i = 1; i <= 200000; ++i)
        fact[i] = (i * fact[i - 1]) % md;

    ll ans1 = c(m, n - 1);
    ll ans2 = n - 2;
    ll ans3 = qpow(2, n - 3);

    ll ans = (ans1 * ans2) % md;
    ans = (ans*ans3)%md;
    cout << ans << endl;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年1月25日2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档