【题解】ABC280E Critical Hit

题目

题目大意

有一生命值为 N N N 的怪兽,你对其攻击一次,有 1 − P 100 1-\frac P{100} 1100P 的概率使其扣 1 1 1 点生命值,有 P 100 \frac P{100} 100P 的概率使其扣 2 2 2 点生命值。求击杀其(指其生命值不大于 0 0 0)的期望攻击次数(   m o d   998244353 \bmod998244353 mod998244353)。

分析

首先你需要了解期望dp

显然,这是一个期望dp的板题。

f [ i ] f[i] f[i] 为怪兽生命值为 i i i 时需要击杀的期望攻击次数,明显地, f [ 0 ] = 0 f[0]=0 f[0]=0

f [ 1 ] = 1 f[1]=1 f[1]=1,因为当其生命值为 1 1 1 时,只要进行 1 1 1 次攻击,无论是扣 1 1 1 点还是 2 2 2 点生命值,怪兽都会死亡。

由于有 1 − P 100 1-\frac P{100} 1100P 的概率扣 1 1 1 点生命值,那么有 1 − P 100 1-\frac P{100} 1100P 的概率由 f [ i − 1 ] f[i-1] f[i1] 转移而来,也就是当怪兽生命值为 i i i 时,有 1 − P 100 1-\frac P{100} 1100P 的概率有如下结果:攻击 1 1 1 次扣 1 1 1 点生命值,此时再攻击 f [ i − 1 ] f[i-1] f[i1] 次就能杀死怪兽。

同理,当怪兽生命值为 i i i 时,有 P 100 \frac P{100} 100P 的概率有如下结果:攻击 1 1 1 次扣 2 2 2 点生命值,此时再攻击 f [ i − 2 ] f[i-2] f[i2] 次就能杀死怪兽。

那么有
f [ i ] = ( 1 − P 100 ) × ( f [ i − 1 ] + 1 ) + P 100 × ( f [ i − 2 ] + 1 ) f[i]=(1-\frac P{100})\times (f[i-1]+1)+\frac P{100}\times (f[i-2]+1) f[i]=(1100P)×(f[i1]+1)+100P×(f[i2]+1)

最终输出 f [ N ] f[N] f[N].

注意这个式子是在   m o d   998244353 \bmod998244353 mod998244353 意义下的,所以对于分数 1 − P 100 = 100 − P 100 1-\frac P{100} = \frac{100-P}{100} 1100P=100100P P 100 \frac{P}{100} 100P 都要在模意义下运算。

我们知道,费马小定理简述如下:

a p − 1 ≡ 1 (   m o d     p ) a^{p-1}\equiv 1(\bmod\space p) ap11(mod p)
其中 p p p 为质数。

那么有

a p − 2 ≡ a − 1 (   m o d     p ) a^{p-2}\equiv a^{-1}(\bmod\space p) ap2a1(mod p)

那么

f [ i ] = ( 100 − P ) × 10 0 − 1 × ( f [ i − 1 ] + 1 ) + P × 10 0 − 1 × ( f [ i − 2 ] + 1 ) f[i]=(100-P)\times 100^{-1}\times (f[i-1]+1)+ P\times 100^{-1}\times (f[i-2]+1) f[i]=(100P)×1001×(f[i1]+1)+P×1001×(f[i2]+1)
= ( 100 − P ) × 10 0 998244353 − 2 × ( f [ i − 1 ] + 1 ) + P × 10 0 998244353 − 2 × ( f [ i − 2 ] + 1 ) =(100-P)\times 100^{998244353-2}\times (f[i-1]+1)+ P\times 100^{998244353-2}\times (f[i-2]+1) =(100P)×1009982443532×(f[i1]+1)+P×1009982443532×(f[i2]+1)

完毕。

code

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 200005;
const LL mod = 998244353;
int n;
LL p, f[N];
LL qpow(LL x, LL y) {
    LL sum = 1;
    while (y) {
        if (y & 1) sum = sum * x % mod;
        x = x * x % mod, y >>= 1;
    }
    return sum;
}
int main() {
    scanf("%d%lld", &n, &p);
    f[1] = 1;
    for (int i = 2; i <= n; i++)
    	f[i] = (p * qpow(100, mod - 2) % mod * (f[i - 2] + 1) % mod + (100 - p) * qpow(100, mod - 2) % mod * (f[i - 1] + 1) % mod) % mod;
    printf("%lld", f[n]);
    return 0;
}

若模数为   m o d   \bmod mod

时间复杂度为 O ( N log ⁡   m o d   ) O(N\log\bmod) O(Nlogmod)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值