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

来源:互联网 发布:贵州省网络测评中心 编辑:程序博客网 时间:2024/06/17 04:55

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 0
原创粉丝点击