Description
Solution
感谢大佬的博客https://www.cnblogs.com/ywwyww/p/8511141.html
定义dp[i]为[p[i],p[i+1])的期望经过次数,f[i]为处理完事件i后不会再回到i点或以前,直接到终点的概率。
则$dp[i]=1+(1-f[i])+(1-f[i])^{2}+......=frac{1}{f[i]}$
设事件i+1的胜率为k。
1:下一个事件是敌人,则f[i]=kf[i+1],即$dp[i]=frac{dp[i+1]}{k}$。
2:下一个事件是旗子,则$f[i]=f[i+1](1+k(1-f[i+1])+k^{2}(1-f[i+1]^{2}+...)=frac{f[i+1]}{1-k+kf[i+1]}$
把f替换为dp得$dp[i]=(1-k)dp[i+1]+k$
Code
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int mod=1e9+7; typedef long long ll; ll ksm(ll x,ll k) { ll re=1; while (k) { if (k&1) re=re*x%mod; k>>=1; x=x*x%mod; } return re; } ll h,n; ll p[100010],a[100010],b[100010];char c[100010][2]; ll dp[100010],ans=0; int main() { scanf("%lld%lld",&h,&n); for (int i=1;i<=n;i++) { scanf("%s%lld%lld%lld",c[i],&p[i],&a[i],&b[i]); a[i]=a[i]*ksm(b[i],mod-2)%mod; } dp[n]=1; for (int i=n;i;i--) if (c[i][0]=='X') dp[i-1]=dp[i]*ksm(a[i],mod-2)%mod; else dp[i-1]=((1-a[i]+mod)%mod*dp[i]%mod+a[i])%mod; p[n+1]=h; for (int i=0;i<=n;i++) ans=(ans+(p[i+1]-p[i])%mod*dp[i]%mod)%mod; cout<<ans; }