JZOJ 5244. 【NOIP2017模拟8.8A组】Daydreamin ' (daydream)

Description

  worldwideD最近有午睡的习惯~
   某日中午,他做了一个梦:梦见有一个怪人,她去一个岛上住N+1天(编号为0到N)。这是在大洋中的岛,每天要么是晴天,要么刮台风。
   她到达岛的第0天是晴天(这样她才能上岸)。然后对于第i天,假如是晴天,那么有P(0<P≤1)的几率会变天:接下来连续M天都刮台风,然后第i+M+1天必然会转晴。
   天气对她的心情会有影响,用一个值来描述她每一天的心情:如果第i天是晴天,那么这个值为A;如果是雨天,那么岛上有D(0<D≤1)的几率会发生杀人案件,如果没发生杀人案件,这个值为B,否则为C。
   worldwideD醒来了,他想知道编号1到N天的心情值之和的期望值。

Description

Input

 一行7个整数N,M,P,D,A,B,C,如题目所描述(其中给出的P,D是模998244353意义下的值)

Output

 一个整数,为答案。

Sample Input

Sample Input1

3 1 499122177 499122177 1 2 3

Sample Input2

233 23 372752072 54252411 10 20 22

Sample Output

Sample Output1

311951365

Sample Output2

651727164

Data Constraint

30%:N≤20
50%:N≤2,000
100%:1≤M≤N≤1,000,000 1≤A,B,C≤1,000 1≤P,D<998244353

Hint

样例一输出的值对应的实数是4.6875

Solution

  • 解决这道题如果直接计算总期望值的话,将会有些困难。

  • 于是我们转而先计算概率。设 F[i] 表示 i 天是晴天的概率

  • 考虑第 i1 天的天气,如果是晴天,那么则有:

    F[i]+=F[i1](1P)

    • 如果是台风天,说明第 i1 天是连续台风天的第 m 天,则第 im1 天必然是上一个晴天。

    • 则有:

      F[i]+=F[im1]P

    • 初始化是: F[0]=1 (第 0 天必定是晴天),于是就可以 O(N) 求出概率了。

    • 接着计算总期望,讨论第 i 天的情况:

    • ①:是晴天,则期望为: F[i]A

    • ②:是台风天,则期望为: (1F[i])(CD+B(1D)) (杀人案件的期望);

    • 那么把这 N 天的①②两种期望全部相加即为答案,时间复杂度为 O(N)

    • 注意:所给的概率都是模意义下的,设给定的模数为 Mo ,处理时都应模 Mo

    • 若给的概率在模意义下为 x ,则概率 1x 就等于 Mo+1x ,证明略。

Code

#include<cstdio>
using namespace std;
const int mo=998244353;
int n,m;
long long p,d,a,b,c,ans;
long long f[1000001];
int main()
{
    scanf("%d%d%lld%lld%lld%lld%lld",&n,&m,&p,&d,&a,&b,&c);
    long long k=(c*d%mo+(mo+1-d)*b%mo)%mo;
    for(int i=f[0]=1,l=mo+1-p;i<=n;i++)
    {
        f[i]=f[i-1]*l%mo;
        if(i-m-1>=0) f[i]=(f[i]+f[i-m-1]*p)%mo;
        ans=(ans+f[i]*a)%mo;
        ans=(ans+(mo+1-f[i])*k)%mo;
    }
    printf("%lld",ans);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值