http://acm.hdu.edu.cn/showproblem.php?pid=6656
题意:有n+1个等级,初始是1级,想要从i级升到i+1级,花费
a
i
a_i
ai,有
p
i
p_i
pi的概率升级成功,
1
−
p
i
1-p_i
1−pi的概率落回
x
i
x_i
xi级去。问从L级升到R级的期望花费。
思路:尽管看起来转移有环,实际上还是线性模型。因为到达i级,只管他第一次到达i级的情形,即
(
i
−
1
)
→
i
(i-1)\rightarrow i
(i−1)→i,不用考虑从高等级失败落回i级。
因此,设
f
(
i
)
:
从
1
级
升
到
i
级
的
期
望
花
费
f(i):从1级升到i级的期望花费
f(i):从1级升到i级的期望花费
f
(
i
+
1
)
=
f
(
i
)
+
a
i
∗
p
i
+
(
1
−
p
i
)
∗
(
a
i
+
f
(
i
+
1
)
−
f
(
x
i
)
)
f(i+1)=f(i)+a_i*p_i+(1-p_i)*(a_i+f(i+1)-f(x_i))
f(i+1)=f(i)+ai∗pi+(1−pi)∗(ai+f(i+1)−f(xi))
化简为:
f
(
i
+
1
)
=
f
(
i
)
+
a
i
∗
p
i
+
(
1
−
p
i
)
∗
(
a
i
−
f
(
x
i
)
)
p
i
f(i+1)=\frac{f(i)+a_i*p_i+(1-p_i)*(a_i-f(x_i))}{p_i}
f(i+1)=pif(i)+ai∗pi+(1−pi)∗(ai−f(xi))。
答案就是
f
(
r
)
−
f
(
l
)
f(r)-f(l)
f(r)−f(l)。
#include<bits/stdc++.h>
using namespace std;
const int maxn=500000+100;
const int mod=1000000000+7;
typedef long long ll;
int T,n,q;
ll f[maxn];
ll pow_mod(ll a,ll n)
{
if(!n)return 1;
ll x=pow_mod(a,n/2);
x=x*x%mod;
if(n&1)x=x*a%mod;
return x;
}
ll inv(ll x){return pow_mod(x,mod-2);}
int main()
{
//freopen("input.in","r",stdin);
cin>>T;
f[1]=0;
int r,s,x,a,l;
while(T--)
{
cin>>n>>q;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&r,&s,&x,&a);
ll p=r*inv(s)%mod;
f[i+1]=(f[i]+a*p+(1-p+mod)*(-f[x]+a+mod))%mod*inv(p)%mod;
}
while(q--)
{
scanf("%d%d",&l,&r);
cout<<(f[r]-f[l]+mod)%mod<<"\n";
}
}
return 0;
}