题解

解法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. gitlab安装指南(gitlab-ce-9.4.3-ce.0.el7.x86_64 centos7)

    1,安装gitlab wget https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-9.4.3-ce.0.el7. ...

  2. winForm入门学习

    Windows窗体 属性: name:对象的名称 windowsState:初始化窗体的大小,Normal,Minimized,Maximized StartPosition:窗体起始位置,Manua ...

  3. EFcore的 基础理解<二> shadow 特性

    接着上一篇.在MyEFTestContext 类中添加这个方法 protected override void OnModelCreating(ModelBuilder modelBuilder) { ...

  4. Maven错误:警告Classpath entry org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER will not be exported or published

    该错误是在我将一个普通的由maven管理的java项目变为javaweb项目后出现的,由警告可以看出是说maven的类路径容器不会被导出或发布(即通过maven管理的依赖不会被导出或发布),那么我们用 ...

  5. chrome浏览器重新安装不了

    1.打开注册表方法1. windows键 + R-->输入regedit-->回车方法2.开始-运行里输入regedit方法3.单击任务栏中windows图标,在搜索程序和文件中输入reg ...

  6. 2.4 使用 xpath 对xml 进行解析

    public class Demo1 { /** * XPath提取XML文档数据 * xpath很强大 用来提取xml文档数据非常方便 * @throws Exception */ public s ...

  7. idea控制台乱码修改

    我的idea当前版本是2019.2.2 试了很多,只有这个有效果 工具类→HELP→Edit Custom VM OPtions中加 -Dfile.encoding=utf-8 然后重启IDEA 这个 ...

  8. vue 之this.$router.push、replace、go的区别

    一.this.$router.push 说明:跳转到指定URL,向history栈添加一个新的记录,点击后退会返回至上一个页面 使用: this.$router.push('/index') this ...

  9. Delphi 类的特性

  10. RabbitMQ 功能

    学习完了rabbitmq总一下 RabbitMQ依赖的语言 erlang 第一它可以实现不同程序之间的程序信息储存交互,在易用性.扩展性.高可用性的方面不俗. rabbitmq相当于一个中间人,我们同 ...