K - Kejin Player
题目大意
升级要钱 a i ai ai,升级有失败的概率 p i pi pi,而失败则会回到 x i xi xi级别。问:给定两个等级 l < r l<r l<r, l l l升到 r r r的期望钱
解题思路:
- 设 f [ i ] f[i] f[i]为 i i i到 i + 1 i + 1 i+1级别的期望钱, s u m [ i ] sum[i] sum[i]为 f [ 1 ] f[1] f[1]到 f [ i ] f[i] f[i]的期望钱的总和, q [ i ] q[i] q[i]为失败概率
- 首先假设当前 i i i层如果失败那么只会返回到 x i = i xi = i xi=i层,由求和式子(高中的错项相消法)可以得出当前 f [ i ] = a i / p i f[i] = ai / pi f[i]=ai/pi
- 再进一步假设返回的 x i = i − 1 xi = i - 1 xi=i−1, 那么 f [ i ] = a i / p [ i ] + ( s u m [ i − 1 ] − s u m [ i − 2 ] ) ∗ q [ i ] f[i] = ai / p[i] + (sum[i - 1] - sum[i - 2]) * q[i] f[i]=ai/p[i]+(sum[i−1]−sum[i−2])∗q[i]
- 然后我们大胆推结论 f [ i ] = a i / p [ i ] + ( s u m [ i − 1 ] − s u m [ x i − 1 ] ) ∗ q [ i ] f[i] = ai / p[i] + (sum[i - 1] - sum[xi - 1]) * q[i] f[i]=ai/p[i]+(sum[i−1]−sum[xi−1])∗q[i]
- 最后因为要对
M
o
d
=
(
1
e
9
+
7
)
Mod = (1e9 + 7)
Mod=(1e9+7)取模,最后的式子即为
f[i] = (a[i] * p[i] % Mod + (sum[i - 1] - sum[x[i] - 1] + Mod) * q[i] % Mod) % Mod;
- 为什么这里的期望符合累加呢?
由于当到达一个点x时,你接下来要发生的事情与之前做的事情没有任何关联,无论你用何种方式到达x,你接下来的待遇都会被一视同仁,也就是我当前的决策对于将来没啥影响。(引用来源:博客)
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const ll Mod = 1000000007;
int T, n, m, r[500100], s[500100], x[500100], a[500100];
ll p[500100], f[500100], sum[500100], q[500100];
void Exgcd(ll a, ll b, ll & x, ll & y) {
if(b == 0) x = 1, y = 0;
else Exgcd(b, a % b, y, x), y -= a / b * x;
}
int main() {
ll tx, ty;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d%d%d%d", &r[i], &s[i], &x[i], &a[i]);
for(int i = 1; i <= n; i++) {
Exgcd(r[i], Mod, tx, ty);
tx = (tx % Mod + Mod) % Mod;
p[i] = s[i] * tx % Mod;
q[i] = (s[i] - r[i]) * tx % Mod;
}
f[1] = a[1] * p[1] % Mod;
sum[1] = f[1];
for(int i = 2; i <= n; i++) {
f[i] = (a[i] * p[i] % Mod + (sum[i - 1] - sum[x[i] - 1] + Mod) * q[i] % Mod) % Mod;//还要考虑失败的概率
sum[i] = (sum[i - 1] + f[i]) % Mod;
}
while(m--) {
scanf("%lld%lld", &tx, &ty);
printf("%lld\n", (sum[ty - 1] - sum[tx - 1] + Mod) % Mod);
}//加Mod是为了防止出现负数
}
return 0;
}