Memory and Casinos CodeForces - 712E (概率,线段树)
题目大意:$n$个点, 每个点$i$有成功率$p_i$, 若成功走到$i+1$, 否则走到走到$i-1$, 多组询问, 求从$l$出发, 在$l$处不失败, 最后在$r$处胜利的概率
设$L[l,r]$表示从$l$出发, 在$l$处不失败, 最后在$r$处胜利的概率,$R[l,r]$表示从$r$出发, 在$l$处不失败, 最后在$r$处胜利的概率
记$l_1=L[l,mid],r_1=L[mid+1,r],l_2=R[l,mid],r_2=R[mid+1,r].$
枚举在$mid$到$mid+1$之间往返的次数, 可以得到下式
$$L[l,r]=l_1l_2\sum\limits_{n=0}^\infty{(1-l_2)^nr_1^n}=\frac{l_1l_2}{1-(1-l_2)r_1}$$
$$R[l,r]=r_2+(1-r_2)r_1l_2\sum\limits_{n=0}^\infty{(1-l_2)^nr_1^n}$$
$$=r_2+(1-r_2)\frac{r_1l_2}{1-(1-l_2)r_1}$$
直接用线段树维护就好了
还有另外一种做法, 考虑询问$[l,r]$
设$f_i$表示从$i$走到$r$且在$r$处胜利的概率, 则答案即为$f_l$
规定$f_{l-1}=0,f_{r+1}=1$ 就有$f_i=(1-p_i)f_{i-1}+p_if_{i+1}$
即$f_i-f_{i-1}=p_i(f_{i+1}-f_{i-1})$
令$g_i=f_i-f_{i-1}$ 则有$g_i=p_i(g_{i+1}-g_{i})$
记$a_i=\frac{1}{p_i}-1,$ 可以得到$g_{i+1}=a_ig_i$
由于$\sum_{i=l}^{r+1}{g_i}=1$
所以就可以得到$f_l=g_l=\frac{1}{1+a_l+a_la_{l+1}+...+a_la_{l+1}\cdot \cdot \cdot a_{r}}$
记$A[l,r]=\prod_{i=l}^{r}{a_i}, B[l,r]=\sum_{i=l}^{r}{A_i}$
有$$A[l,r]=A[l,mid]A[mid+1,r]$$
$$B[l,r]=B[l,mid]+A[l,mid]B[mid+1,r]$$
线段树维护$A,B$即可
第一种代码
#include <iostream>
#include <algorithm>
#include <math.h>
#include <cstdio>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define mid ((l+r)>>1)
#define lc (o<<1)
#define rc (lc|1)
#define ls lc,l,mid
#define rs rc,mid+1,r
using namespace std; const int N = 1e5+;
int n, m;
struct _ {
double L, R;
_ () {}
_ (int x, int y) {L=R=(double)x/y;}
_ (double l,double r) :L(l),R(r) {}
_ operator + (const _ &rhs) const {
return _(L*rhs.L/(-(-rhs.L)*R),rhs.R+(-rhs.R)*R*rhs.L/(-(-rhs.L)*R));
}
} v[N<<]; void build(int o, int l, int r) {
if (l==r) {
int x, y;
scanf("%d%d", &x, &y);
v[o]=_(x,y);
return;
}
build(ls),build(rs),v[o]=v[lc]+v[rc];
} void upd(int o, int l, int r, int pos, int x, int y) {
if (l==r) return v[o]=_(x,y),void();
if (mid>=pos) upd(ls,pos,x,y);
else upd(rs,pos,x,y);
v[o]=v[lc]+v[rc];
} _ qry(int o, int l, int r, int ql, int qr) {
if (ql<=l&&r<=qr) return v[o];
if (mid<ql) return qry(rs,ql,qr);
if (mid>=qr) return qry(ls,ql,qr);
return qry(ls,ql,qr)+qry(rs,ql,qr);
} int main() {
scanf("%d%d", &n, &m);
build(,,n);
REP(i,,m) {
int op, pos, a, b;
scanf("%d", &op);
if (op==) {
scanf("%d%d%d", &pos, &a, &b);
upd(,,n,pos,a,b);
} else {
scanf("%d%d", &a, &b);
printf("%.12lf\n", qry(,,n,a,b).L);
}
}
}
第二种完全类似, 改下公式就行了
#include <iostream>
#include <algorithm>
#include <math.h>
#include <cstdio>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define mid ((l+r)>>1)
#define lc (o<<1)
#define rc (lc|1)
#define ls lc,l,mid
#define rs rc,mid+1,r
using namespace std; const int N = 1e5+;
int n, m;
struct _ {
double A, B;
_ () {}
_ (int x, int y) {A=B=(double)y/x-;}
_ (double a,double b) :A(a),B(b) {}
_ operator + (const _ &rhs) const {
return _(A*rhs.A,B+A*rhs.B);
}
} v[N<<]; void build(int o, int l, int r) {
if (l==r) {
int x, y;
scanf("%d%d", &x, &y);
v[o]=_(x,y);
return;
}
build(ls),build(rs),v[o]=v[lc]+v[rc];
} void upd(int o, int l, int r, int pos, int x, int y) {
if (l==r) return v[o]=_(x,y),void();
if (mid>=pos) upd(ls,pos,x,y);
else upd(rs,pos,x,y);
v[o]=v[lc]+v[rc];
} _ qry(int o, int l, int r, int ql, int qr) {
if (ql<=l&&r<=qr) return v[o];
if (mid<ql) return qry(rs,ql,qr);
if (mid>=qr) return qry(ls,ql,qr);
return qry(ls,ql,qr)+qry(rs,ql,qr);
} int main() {
scanf("%d%d", &n, &m);
build(,,n);
REP(i,,m) {
int op, pos, a, b;
scanf("%d", &op);
if (op==) {
scanf("%d%d%d", &pos, &a, &b);
upd(,,n,pos,a,b);
} else {
scanf("%d%d", &a, &b);
printf("%.12lf\n", /(+qry(,,n,a,b).B));
}
}
}
Memory and Casinos CodeForces - 712E (概率,线段树)的更多相关文章
- Codeforces 787D. Legacy 线段树建模+最短路
D. Legacy time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- CodeForces 91B Queue (线段树,区间最值)
http://codeforces.com/problemset/problem/91/B B. Queue time limit per test: 2 seconds memory limit p ...
- Vasya and a Tree CodeForces - 1076E(线段树+dfs)
I - Vasya and a Tree CodeForces - 1076E 其实参考完别人的思路,写完程序交上去,还是没理解啥意思..昨晚再仔细想了想.终于弄明白了(有可能不对 题意是有一棵树n个 ...
- loj2537 「PKUWC2018」Minimax 【概率 + 线段树合并】
题目链接 loj2537 题解 观察题目的式子似乎没有什么意义,我们考虑计算出每一种权值的概率 先离散化一下权值 显然可以设一个\(dp\),设\(f[i][j]\)表示\(i\)节点权值为\(j\) ...
- CodeForces 19D Points (线段树+set)
D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- Codeforces 240F. TorCoder 线段树
线段树统计和维护某一区间内的字母个数.. . . F. TorCoder time limit per test 3 seconds memory limit per test 256 megabyt ...
- Almost Regular Bracket Sequence CodeForces - 1095E (线段树,单点更新,区间查询维护括号序列)
Almost Regular Bracket Sequence CodeForces - 1095E You are given a bracket sequence ss consisting of ...
- Sereja and Brackets CodeForces - 380C (线段树+分治思路)
Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...
- Glass Carving CodeForces - 527C (线段树)
C. Glass Carving time limit per test2 seconds memory limit per test256 megabytes inputstandard input ...
随机推荐
- Ignite初探
Guava是一个很方便的本地缓存工具,但是在多节点处理的过程中,本地缓存无法满足数据一致性的问题.分布式缓存Ignite很好的解决了数据一致性,可靠性,事务性等方面的问题. Ignite支持分区方式和 ...
- linux常用命令:gzip 命令
减 少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间.gzip是在Linux系统中经常使用的一个对文件进 行压缩和解压缩的命令,既方便又好用.gzip不仅可 ...
- zendstudio中加入对tpl文件的支持,用HTML Editor编辑器编辑
zendstudio中加入对tpl文件的支持,用HTML Editor编辑器编辑:ThinkPHP中默认使用的tpl在zendstudio中默认打开都是文本编辑器的,没有语法提示开发效率很低,直接设置 ...
- Python之路----各类推导式
[每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型] #遍历之后挨个处理[满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] #筛选功能 列表推导 ...
- 【运维技术】Maven + Gogs + Nexus 实现版本管理 + 代码模块开发管理
Gogs:能够实现fork + 代码提交 + 代码框架 Nexus:进行jar包的版本管理,私服下载jar包共享jar包 Maven:在客户端进行模块管理和批量操作 1. 本地maven仓库配置配置s ...
- python模块-json、pickle、shelve
json模块 用于文件处理时其他数据类型与js字符串之间转换.在将其他数据类型转换为js字符串时(dump方法),首先将前者内部所有的单引号变为双引号,再整体加上引号(单或双)转换为js字符串:再使用 ...
- swagger报错No handler found for GET /swagger-ui.html
今天下载jeeweb框架下来研究,其他还有,就是swagger老是出不来.报错:No handler found for GET /swagger-ui.html 后来搜索才发现,这个错误,是因为资源 ...
- Educational Codeforces Round 21 Problem A - C
Problem A Lucky Year 题目传送门[here] 题目大意是说,只有一个数字非零的数是幸运的,给出一个数,求下一个幸运的数是多少. 这个幸运的数不是最高位的数字都是零,于是只跟最高位有 ...
- noip2008 真题练习 2017.2.25
不是有很多可以说的,记住不能边算边取min Code #include<iostream> #include<fstream> #include<sstream> ...
- Linux系统编程--文件描述符的复制dup()和dup2()【转】
本文转载自:http://blog.csdn.net/tennysonsky/article/details/45870459 dup() 和 dup2() 是两个非常有用的系统调用,都是用来复制一个 ...