题解

解法1:(官方做法)

一段区间的\(L\)定义为从最左边开始出发,最左不失败,一直到最右边胜利的概率,\(R\)定义为从最右边开始出发,最左不失败,又回到最右边胜利的概率

考虑一个区间\([l, r]\)记为\(u\),左右儿子\([l, mid]\)和\([mid + 1, r]\)分别记为\(ls\)和\(rs\)

枚举一下\(mid\)和\(mid+1\)之间往返多少次

\[u.L = ls.L * rs.L * \sum_{i = 0}^{\infty} ls.R^i(1-rs.L)^i
\]

这玩意是无穷项等比数列求和:

\[u.L = \frac{ls.L * rs.L}{1 - ls.R * (1 - rs.L)}
\]

\(u.R\)分不过和过\(mid\)两种情况

\[u.R = rs.R + (1 - rs.R)*rs.L*ls.R\sum_{i = 0}^{\infty} (1 - rs.L)^i ls.R^i
\]

\[u.R = rs.R + (1 - rs.R)\frac{rs.L* ls.R}{1 - ls.R(1 - rs.L)}
\]

#include <algorithm>
#include <cstdio>
using namespace std; const int N = 1e5 + 10; struct node {
double L, R;
void rd() {
int x, y;
scanf("%d%d", &x, &y);
L = R = x * 1.0 / y;
}
} a[N << 2];
int n, q; node operator + (const node &ls, const node &rs) {
node ans;
ans.L = ls.L * rs.L / (1 - ls.R * (1 - rs.L));
ans.R = rs.R + (1 - rs.R) * rs.L * ls.R / (1 - ls.R * (1 - rs.L));
return ans;
} void build(int rt, int l, int r) {
if(l == r) {
a[rt].rd();
return ;
}
int mid = (l + r) >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
a[rt] = a[rt << 1] + a[rt << 1 | 1];
} void modify(int rt, int l, int r, int x, double p) {
if(l == r) {
a[rt].L = a[rt].R = p;
return ;
}
int mid = (l + r) >> 1;
if(x <= mid) modify(rt << 1, l, mid, x, p);
else modify(rt << 1 | 1, mid + 1, r, x, p);
a[rt] = a[rt << 1] + a[rt << 1 | 1];
} node query(int rt, int l, int r, int ql, int qr) {
if(l == ql && r == qr) return a[rt];
int mid = (l + r) >> 1;
if(qr <= mid) return query(rt << 1, l, mid, ql, qr);
if(ql > mid) return query(rt << 1 | 1, mid + 1, r, ql, qr);
return query(rt << 1, l, mid, ql, mid) + query(rt << 1 | 1, mid + 1, r, mid + 1, qr);
} int main() {
scanf("%d%d", &n, &q);
build(1, 1, n);
int op, x, y, z;
while(q --) {
scanf("%d%d%d", &op, &x, &y);
if(op == 1) {
scanf("%d", &z);
modify(1, 1, n, x, y * 1.0 / z);
}
if(op == 2) {
printf("%.10f\n", query(1, 1, n, x, y).L);
}
}
return 0;
}

解法2

\(dp[i]\)表示从\(i\)开始成功的概率

令\(dp[l - 1] = 0, dp[r + 1] = 1\),则\(dp[i] = dp[i - 1] * (1 - p[i]) + dp[i + 1] * p[i]\)

化简得:\(dp[i] - dp[i - 1] = p[i] * (dp[i + 1] - dp[i - 1])\)

令\(d[i] = dp[i] - dp[i - 1]\)

\(d[i] = p[i] * (d[i + 1] + d[i])\)

解得:\(d[i + 1] = \frac{1 - p[i]}{p[i]} d[i]\)

为了简便,令\(u[i] = \frac{1 - p[i]}{p[i]}\)

则递推式为\(d[i + 1] = u[i] * d[i]\)

考虑我们怎么求\(dp[l]\)(即\(d[l]\))

\(d[l] + d[l+1] + ... + d[r + 1] = dp[r + 1] - dp[l] = 1\)

所以\(d[l] (1 + u[l] + u[l] * u[l + 1] + ... + u[l] * u[l + 1] * u[l + 2] * .. * u[r]) = 1\)

\(d[l] = \frac{1}{1 + u[l] + u[l] * u[l + 1] + ... + u[l] * u[l + 1] * u[l + 2] * .. * u[r]}\)

线段树维护两个东西,一个是\(u\)的乘积,一个是所有前缀的乘积和,就做完了

代码就不写了

「CF712E」Memory and Casinos「线段树」「概率」的更多相关文章

  1. 「BZOJ2733」「洛谷3224」「HNOI2012」永无乡【线段树合并】

    题目链接 [洛谷] 题解 很明显是要用线段树合并的. 对于当前的每一个连通块都建立一个权值线段树. 权值线段树处理操作中的\(k\)大的问题. 如果需要合并,那么就线段树暴力合并,时间复杂度是\(nl ...

  2. 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树

    题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...

  3. 【tyvj】P2065 「Poetize10」封印一击(贪心+线段树/差分)

    http://new.tyvj.cn/p/2065 我就不说我很sb的用线段树来维护值...... 本机自测的时候想了老半天没想出怎么维护点在所有区间被多少区间包含的方法.最后一小时才想出来线段树(果 ...

  4. 【CF712E】Memory and Casinos(数学 期望 DP)

    题目链接 大意 给出一个序列,当你在某个点时,有一个向右走的概率\(P_i\)(向左为\(1-P_i\)), 给出\(M\)个操作,操作有两类: 1 X Y Z:把\(P_X\)的值修改为\(\fra ...

  5. 「10.29」数列(exgxd)·数对(线段树优化DP)·最小距离(最短路,树上直径思想)

    好久没碰到这么友好乱搞的题了.... A. 数列 考察的是exgcd的相关知识,最后的答案直接O(1)求即可 B. 数对 本来以为是原题,然后仔细看了看发现不是,发现不会只好乱搞骗分了 事实上直接按$ ...

  6. 【线段树 集合hash】bzoj4373: 算术天才⑨与等差数列

    hash大法好(@ARZhu):大数相乘及时取模真的是件麻烦事情 Description 算术天才⑨非常喜欢和等差数列玩耍.有一天,他给了你一个长度为n的序列,其中第i个数为a[i].他想考考你,每次 ...

  7. 「ZJOI2017」树状数组(二维线段树)

    「ZJOI2017」树状数组(二维线段树) 吉老师的题目真是难想... 代码中求的是 \(\sum_{i=l-1}^{r-1}a_i\),而实际求的是 \(\sum_{i=l}^{r}a_i\),所以 ...

  8. LOJ #2359. 「NOIP2016」天天爱跑步(倍增+线段树合并)

    题意 LOJ #2359. 「NOIP2016」天天爱跑步 题解 考虑把一个玩家的路径 \((x, y)\) 拆成两条,一条是 \(x\) 到 \(lca\) ( \(x, y\) 最近公共祖先) 的 ...

  9. 【LibreOJ】#6396. 「THUPC2018」弗雷兹的玩具商店 / Toyshop 线段树+完全背包

    [题目]#6396. 「THUPC2018」弗雷兹的玩具商店 / Toyshop [题意]给定一个长度为n的物品序列,每个物品有价值.不超过m的重量.要求支持以下三种操作:1.物品价值区间加减,2.物 ...

随机推荐

  1. 并不对劲的CF1236D&E:Alice&Doll&UnfairGame

    CF1236D Alice&Doll 题目描述 有一个机器人在一个\(n\times m\)的有\(k\)个障碍网格上移动,上北下南左西右东. 它一开始在第一行第一列,面朝东边.它在每个格子上 ...

  2. promise, async和await

    最开始实现异步的方法:回调函数 method1(function(err, result) { if (err) { throw err; } method2(function(err, result ...

  3. JS中逗号运算符的用法

    逗号运算符,它将先计算左边的参数,再计算右边的参数值.然后返回最右边参数的值. 原书举的例子不太好,无法解释上面那句话,这里另外提供一个: var a = 10, b = 20; function C ...

  4. sonarqube执行命令遇上的小问题

    在安装好sonarqube,本地或是服务器上都是可疑正常运行的情况下. 这一次我重新上传,修改配置SonarQube.Analysis.xml,sonar.host.url的值已经改为服务器上的,执行 ...

  5. JS 编程艺术

    JS艺术片段剪贴 getFullDate: function (date) { //返回 YYYY年MM月DD日 var year = month = day = ' '; if (isNaN(dat ...

  6. selenium 12306模拟登陆

    代码应用场景 :基于第三方打码网站模拟登陆12306 验证码识别 基于第三方平台超级鹰识别 超级鹰官网:http://www.chaojiying.com/user/ 超级鹰使用流程: 注册 登陆(用 ...

  7. 基于Vue实现拖拽效果

    参考地址:基于Vue实现拖拽效果 参考链接中讲的比较详细,我只使用了其中自定义指令的方法.整体代码如下: <template> <!-- 卡片 --> <div clas ...

  8. Spring Cloud(O)服务的注册与发现(Eureka)

    一.微服务架构 1.1什么是分布式 不同模块部署在不同服务器上 作用:分布式解决网站高并发带来问题 1.2什么是集群 多台服务器部署相同应用构成一个集群 作用:通过负载均衡设备共同对外提供服务 1.3 ...

  9. 使用pycharm 编写代码 并在远程主机上运行

    一 要求 远程主机有python解释器 二 在菜单栏,File -> Settings… -> Project ×× -> Project Interpreter,点击右侧 Add按 ...

  10. Short XSS

    Short XSS Crackkay · 2013/08/21 12:17 0x00 背景 关键时候长度不够怎么办? 在实际的情况中如果你不够长怎么办呢?看医生?吃药?做手术?............ ...