牛客小白赛14 B.投硬币

题目链接

题目描述

你在练习 d p dp dp,你每一次会有 p p p 的概率成功, 1 − p 1-p 1p 的概率失败

求投 n n n 次后,至少有 k k k 次成功的概率

答案模 998244353 998244353 998244353,其中 0 ≤ k , n ≤ 1 0 5 , 0 ≤ p &lt; 998244353 0\leq k,n\leq10^5,0\leq p&lt;998244353 0k,n105,0p<998244353

实际上给你的这个概率是在模 998244353 998244353 998244353 意义下的,换句说 p ≡ a b ( m o d 998244353 ) p\equiv \frac{a}{b}(mod998244353) pba(mod998244353)

输入描述

第一行三个整数 n , k , p n,k,p n,k,p

输出描述

一行一个整数表示答案对 998244353 998244353 998244353取模的结果

示例1
输入
34 21 56
输出
345738771
题目大意

题干描述的直接大白,就是一道概率题。

思路

题目说求 n n n次练习后,至少有 k k k次成功的概率,换句话说就是求 k , k + 1 , k + 2 ⋯ n k,k+1,k+2 \cdots n k,k+1,k+2n次成功概率之和即 ∑ k n ( i n ) p i ( 1 − p ) n − i \sum_{k}^{n}(_i^n)p^i(1-p)^{n-i} kn(in)pi(1p)ni

AC代码
#include <bits/stdc++.h>
const long long mod=998244353;
const int Max_N=1e5+100;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll fac[Max_N],inv[Max_N];
ll q_pow(ll a,ll b)//快速幂取余
{
    ll ans=1;
    while(b)
    {
        if(b&1)
            ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
ll C(ll n,ll m)//组合函数
{
    //补充a/bmodc=a*inv[a]modc
    return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main(int argc, char const *argv[])
{
    int n,k,p;
    cin>>n>>k>>p;
    fac[0]=1,fac[1]=1;
    for(int i=2;i<=n;i++)//预处理阶乘
    {
        fac[i]=i*fac[i-1]%mod;
    }
    inv[n]=q_pow(fac[n],mod-2);
    //先求出n!的乘法逆元,这里用的是费马小定理,但前提是gcd(fac[n],mod)=1
    for(int i=n-1;i>=0;i--)
    {
        inv[i]=(i+1)*inv[i+1]%mod;
    }
    /*依据阶乘逆元的性质,在O(n)中求出各个阶乘的逆元,除了求逆元的方法特殊外
      其他情况是都可以把逆元看作是倒数来计算
    */
    ll res=0;
    for(int i=k;i<=n;i++)
    {
        res=(res+C(n,i)*q_pow(p,i)%mod*q_pow(1-p+mod,n-i)%mod)%mod;
        //当1-p小于0时,加一个mod
    }
    res%=mod;
    cout<<res<<endl;
    return 0;
}
总结

说实话,这道题花了很长时间,虽然题目的原理很简单,但要补很多知识点,其中一个就是求乘法逆元的方法,之前接触过,但不熟,最简单的一种方法就是用费马小定理(核心代码是快速幂取余),还有一种方法是利用扩展欧几里得方法来计算,但碍于自己对扩展欧几里得定理的心理阴影,所以没有选择扩展欧几里得方法。同时也学到了在 O ( n ) O(n) On的时间里求出阶乘的乘法逆元。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值