uoj#299. 【CTSC2017】游戏 & bzoj4902

来源:互联网 发布:java语言程序设计 一 编辑:程序博客网 时间:2024/06/05 22:37

小 R 和室友小 B 在寝室里玩游戏。他们一共玩了 n 局游戏,每局游戏的结果要么是小 R 获胜,要么是小 B 获胜。

第 11 局游戏小 R 获胜的概率是 p1,小 B 获胜的概率是 1−p1。除了第一局游戏之外,每一局游戏小 R 获胜的概率与上一局游戏小 R 是否获胜有关。

具体来说:

如果第 i−1 (1<i≤n) 局游戏小 R 获胜,那么第 i 局游戏小 R 获胜的概率为 pi,小 B 获胜的概率为 1−pi。如果第 i−1 (1<i≤n) 局游戏小 B 获胜,那么第 i 局游戏小 R 获胜的概率为 qi,小 B 获胜的概率为 1−qi。

小 D 时常过来看小 R 和小 B 玩游戏,因此他知道某几局游戏的结果。他想知道在他已知信息的条件下,小 R 在 n 局游戏中获胜总局数的期望是多少。

小 D 记性不太好,有时他会回忆起某局游戏的结果,并把它加入到已知信息中;有时他会忘记之前某局游戏结果,并把它从已知信息中删除。你的任务是:每当小 D 在已知信息中增加或删除一条信息时,根据小 D 记得的已知信息,帮助小 D 计算小 R 在 n 局游戏中获胜总局数的期望是多少。

需要注意的是:如果小 D 忘了一局游戏的结果,之后又重新记起,两次记忆中的游戏结果不一定是相同的。你不需要关心小 D 的记忆是否与实际情况相符,你只需要根据他的记忆计算相应的答案。
输入格式

第一行两个正整数 n,m 和一个字符串 type。表示小 R 和小 B 一共玩了 n 局游戏,小 D 一共进行了 m 次修改已知信息的操作,该数据的类型为 type。type 字符串是为了能让大家更方便地获得部分分,你可能不需要用到这个输入,其具体含义见限制与约定。

接下来 n 行,第 1 行包含一个实数 p1,表示第一局比赛小R获胜的概率是 p1。第 i (1< i≤n) 行包含两个实数 pi,qi。表示在第 i−1 局游戏小 R 获胜的情况下,第 i 局游戏小 R 获胜的概率是 pi;qi 表示在第 i−1 局游戏小 B 获胜的情况下,第 i 局游戏小 R 获胜的概率是 qi。

接下来 m 行,每行描述一个小 D 已知信息的变化,操作分为两类。

add i c 表示小 D 回忆起了第 i 局比赛的结果,并把它加入到已知信息中。若 c=0 表示第 i 局比赛小 B 获胜,若 c=1 表示第 i 局比赛小 R 获胜。数据保证 i,c 均为整数且 1≤i≤n,0≤c≤1,如果这个操作不是第一个操作,保证在上一个操作结束后的已知信息中没有第 i 局比赛的结果。del i 表示小 D 忘记了第 i 局比赛的结果,并把它从已知信息中删除。数据保证 i 是整数且 1≤i≤n,保证在上一个操作结束后的已知信息中有第 i 局比赛的结果。

输出格式

对于每个操作,输出一行实数,表示操作结束后,在当前已知信息的条件下,小R在 n 局游戏中总共获胜的局数的期望是多少。
样例一
input

3 3 A
0.3
0.5 0.2
0.9 0.8
add 1 1
add 3 0
del 1

output

2.350000
1.333333
0.432749

刚刚打到一半莫名挂掉了。。。简单写了。
一段没有一场确定游戏的区间的贡献之和之和前边一场确定的和后边一场确定的有关。
用一下贝叶斯公式,分母是常数,分子是一堆长得很像的乘积。
只要快速算出分子,答案就可以在之前的答案的基础上把一个区间分割开或者合并两个区间。
注意到一段区间[l,r]如果有在x1和x2场分别赢or输的胜场期望的话可以转移到在x0和x2场赢or输的期望,或者转移到x1和x3场赢or输的期望。(x0<=x1<=l<=r<=x2<=x3)
计算方法是枚举x1-1场的输赢然后计算。(通过贝叶斯公式考虑)
这样的话用线段树维护每个线段[l,r]在l-1和r+1已知的情况下的期望。
查询时把logn个线段扩展到左边确定的场是l右边确定的是r的情况就可以了。
注意每次找到线段,不能直接扩展到左右,要和线段树查询维护的范围一样,一同扩展,这样每次merge区间的复杂度O(1)。总复杂度是O(mlogn)。
否则是log2n 的单次复杂度,会TLE。
(也可以用矩阵转移来看这个dp?)

原创粉丝点击