2019杭电暑期多校第七场 K:Kejin Player(期望dp+逆元)

【题解】

题意:给定从第 i 级升到第 i+1 级的成功概率 pi=ri/si ,失败降到 xi 级,花费 ai 人民币。q 个询问,每次问从 l 级升到 r 级需要多少钱。

思路:设从 l 到 r 的期望为 g(l,r),因为升级只能一级一级升,所以要从 1 升级到 r 必然要经过 l ,所以这种期望满足可加减性,因此可以得到 g(l,r) = g(1,r) -g(1,l) 。那么我们可以降维以前缀和的形式实现,令 dp[i] 表示从第1级升级到第 i 级的期望,那么 g[l,r]=dp[r]-dp[l] 。

从第 i 级升级到 i+1级,有 pi 的概率只花费 ai ,有 1-pi 的概率降到 xi 级 ,又概率为pi 期望为 1/pi ,因此可以推出式子:

dp[i]=(1/pi)*ai+(1/(1-pi))*(dp[i-1]-dp[x])

【代码】

#include
using namespace std;
#define ll long long
const int mod=1e9+7;
const int maxn=5e5+10;
ll dp[maxn];
ll qpow(ll a, ll b)
{
    ll tmp=1;
    while(b){
        if(b&1) tmp=tmp*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return tmp;
}
int main()
{
    int T; scanf("%d",&T);
    while(T--){
        int n,q; scanf("%d%d",&n,&q);
        dp[1]=0;
        for(int i=2;i<=n+1;++i){
            ll r,s,x,a;
            scanf("%lld%lld%lld%lld",&r,&s,&x,&a);
            dp[i]=(s*a%mod+(s-r)*(dp[i-1]-dp[x]+mod)%mod)%mod*qpow(r,mod-2)%mod;
            dp[i]=(dp[i-1]+dp[i])%mod;
        }
        while(q--){
            int l,r; scanf("%d %d",&l,&r);
            printf("%lld\n",(dp[r]-dp[l]+mod)%mod);
        }
    }
    return 0;
}

 

你可能感兴趣的:(2019杭电暑期多校第七场 K:Kejin Player(期望dp+逆元))