2019杭电多校 第七场 Kejin Player 6656(求期望值)
题目
http://acm.hdu.edu.cn/showproblem.php?pid=6656
题意
给你n,q。表示有n个等级,q次询问。
接下来n行有r, s, x, a四个数据表示小明从上一级升到下一级需要a经验,有r/s的几率成功,如果失败就回到第x级。(小明一开始是1级)
后面还有q行,问你从L级升到R级需要多少经验?
答案还需要模109+7.
题解
我们可以用前缀和的方式求出到每级所需要的钱。
升级所需要花费的钱数 = (a+tmp【从x级升到i-1级需要的经验】)*(s-r)*r-(这里要求逆元)取模再加a。
把花费a成功的概率当作单位1。
代码
#include<iostream>
#include<string.h>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const int mod = 1e9 + 7;
const int maxn = 1e6 + 5;
ll qpow(ll a,ll n)
{
ll ans = 1;
while(n)
{
if(n&1)
ans = ans*a%mod;
a = a*a%mod;
n >>= 1;
}
return ans;
}
ll sum[maxn];
int T,n,q;
int main()
{
scanf("%d",&T);
while(T--)
{
mem(sum,0);
scanf("%d %d",&n,&q);
for(int i = 1;i<=n;i++)
{
ll r,s,x,a;
scanf("%lld %lld %lld %lld",&r,&s,&x,&a);
ll tmp = (sum[i - 1] - sum[x - 1] + mod) % mod;//从x级升到i-1级需要的经验
sum[i] = (a+tmp) %mod * (s - r) %mod * qpow(r,mod-2) % mod;
sum[i] = (sum[i] + a %mod) %mod;
sum[i] = (sum[i] + sum[i-1]) %mod;
}
for(int i = 1;i<=q;i++)
{
ll l,r;
scanf("%lld %lld",&l,&r);
printf("%lld\n",(sum[r-1] - sum[l-1] + mod)%mod);
}
}
return 0;
}