2019 Multi-University Training Contest 7 Kejin Player 期望dp

题目传送门

题意:有n个等级,在每个等级花费$ai$的代价有$pi$的几率升到$i+1$级,$1-pi$的概率降级降到$xi$(xi<=i),给出q次询问,每次询问从$l$级到$r$级的代价的期望。

思路:

  此题的期望是满足加减的,即<l,r>的期望等于<1,r>的减去<1,l>的。

  设$E[i][j]$表示从i级升到j级需要付出的额外代价。

  则由$E[i][i+1]=ai*pi+(1-pi)*(ai+E[xi][i+1])$

      =$ai*pi+(1-pi)(ai+E[xi][i]+E[i][i+1])$。

  移项、合并同类型可得 $pi*E[i][i+1]=ai*pi+(1-pi)*ai+(1-pi)*E[xi][i]$。如果从1到n递推,对于i来说,这个式子右边都是已知的,所以可以求出。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,b,a) for(int i=b;i>=a;i--)
#define clr(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pii pair<int,int >
using namespace std;
typedef long long ll;
ll rd() {
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9') {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
const int maxn=500000+10;
ll mod=1e9+7;
ll qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)res=res*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}
ll n,q,m,k,T;
ll r[maxn],s[maxn],x[maxn],a[maxn],dis[maxn],p[maxn];
int main(){
    cin>>T;
    while(T--){
        scanf("%lld%lld",&n,&q);
        for(int i=1;i<=n;i++){
            scanf("%lld%lld%lld%lld",&r[i],&s[i],&x[i],&a[i]);
            p[i]=((s[i]-r[i]+mod)%mod)*qpow(r[i],mod-2)%mod;
        }
        rep(i,1,n){
            dis[i+1]=((dis[i]+a[i])%mod+p[i]*a[i]%mod+(dis[i]-dis[x[i]]+mod)%mod*p[i]%mod+mod)%mod;
        }
        while(q--){
            ll l,r;
            scanf("%lld%lld",&l,&r);
            printf("%lld\n",(dis[r]-dis[l]+mod)%mod);
        }
    }
} 

 

posted @ 2019-08-12 19:42  光芒万丈小太阳  阅读(193)  评论(0编辑  收藏  举报