博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces 712E Memory and Casinos
阅读量:5226 次
发布时间:2019-06-14

本文共 5011 字,大约阅读时间需要 16 分钟。

Description

There are n casinos lined in a row. If Memory plays at casino \(i\), he has probability \(p_{i}\) to win and move to the casino on the right \((i + 1)\) or exit the row (if \(i = n\)), and a probability \(1 - p_{i}\) to lose and move to the casino on the left \((i - 1\)) or also exit the row (if \(i = 1\)).

We say that Memory dominates on the interval \(i \dots j\) if he completes a walk such that,
\(\bullet\)He starts on casino \(i\).
\(\bullet\)He never looses in casino \(i\).
\(\bullet\)He finishes his walk by winning in casino \(j\).
Note that Memory can still walk left of the 1-st casino and right of the casino n and that always finishes the process
Now Memory has some requests, in one of the following forms:
\(1 i a b\): Set \(p_{i} = \frac{a}{b}\).
\(2 l r\): Print the probability that Memory will dominate on the interval \(l \dots r\), i.e. compute the probability that Memory will first leave the segment \(l \dots r\) after winning at casino \(r\), if she starts in casino \(l\).
It is guaranteed that at any moment of time p is a non-decreasing sequence, i.e. \(p_{i} \le  p_{i + 1}\) for all \(i\) from \(1\) to \(n - 1\).
Please help Memory by answering all his requests!

Input

The first line of the input contains two integers \(n\) and \(q(1  \le  n, q \le 100 000)\), — number of casinos and number of requests respectively.

The next n lines each contain integers \(a_{i}\) and \(b_{i}\) \((1 \le a{i} < b_{i} \le 10^{9})\) — is the probability \(p_{i}\) of winning in casino \(i\).
The next q lines each contain queries of one of the types specified above (1 ≤ a < b ≤ 109, 1 ≤ i ≤ n, 1 ≤ l ≤ r ≤ n).
It's guaranteed that there will be at least one query of type \(2\), i.e. the output will be non-empty. Additionally, it is guaranteed that p forms a non-decreasing sequence at all times.

Output

Print a real number for every request of type \(2\) — the probability that boy will "dominate" on that interval. Your answer will be considered correct if its absolute error does not exceed \(10^{-4}\).

Namely: let's assume that one of your answers is \(a\), and the corresponding answer of the jury is \(b\). The checker program will consider your answer correct if \(\mid a - b \mid \le  10^{ - 4}\).

Sample Input

3 13

1 3
1 2
2 3
2 1 1
2 1 2
2 1 3
2 2 2
2 2 3
2 3 3
1 2 2 3
2 1 1
2 1 2
2 1 3
2 2 2
2 2 3
2 3 3

Sample Output

0.3333333333

0.2000000000
0.1666666667
0.5000000000
0.4000000000
0.6666666667
0.3333333333
0.2500000000
0.2222222222
0.6666666667
0.5714285714
0.6666666667

对于区间\(l \dots r\),我们用\(f\)记录成功离开区间的概率,\(g\)记录从\(r\)出发最后到\(r+1\),没有离开过区间的概率。\(f_{1},g_{1}\)\(l \dots mid\)\(f,g\)值,\(f_{2},g_{2}\)\(mid+1 \dots r\)\(f,g\)值。合并方程:

\[f = f_{1}f_{2}+f_{1}(1-f_{2})g_{1}f_{2}+\cdots=\frac{f_{1}f_{2}}{1-(1-f_{2})g_{1}}\]
\[g = g_{2}+(1-g_{2})g_{1}f_{2}+(1-g_{2})g_{1}(1-f_{2})g_{1}f_{2}+\cdots=g_{2}+\frac{(1-g_{2})g_{1}f_{2}}{1-(1-g_{2})g_{1}}\]
线段树维护下。

#include
#include
#include
using namespace std;typedef long double ld;#define maxn (400010)int N,Q,A[maxn],B[maxn],lef[maxn]; ld g[maxn],f[maxn];struct node { ld f,g; };inline int gi(){ int f = 1,ret = 0; char ch; do ch = getchar(); while (!(ch >= '0'&&ch <= '9')&&ch != '-'); if (ch == '-') f = -1,ch = getchar(); do ret = ret*10+ch-'0',ch = getchar(); while (ch >= '0'&&ch <= '9'); return f*ret;}inline void build(int now,int l,int r){ if (l == r) { lef[l] = now; g[now] = f[now] = (ld)A[l]/(ld)B[l]; return; } int mid = (l+r)>>1; build(now<<1,l,mid); build(now<<1|1,mid+1,r); f[now] = (f[now<<1]*f[now<<1|1])/(1-g[now<<1]*(1-f[now<<1|1])); g[now] = g[now<<1|1]+(1-g[now<<1|1])*g[now<<1]*f[now<<1|1]/(1+(f[now<<1|1]-1)*g[now<<1]);}inline node query(int now,int l,int r,int ql,int qr){ if (l == ql&&r == qr) return (node){ f[now],g[now] }; int mid = (l+r)>>1; if (qr <= mid) return query(now<<1,l,mid,ql,qr); else if (ql > mid) return query(now<<1|1,mid+1,r,ql,qr); else { node a,b,ret; a = query(now<<1,l,mid,ql,mid); b = query(now<<1|1,mid+1,r,mid+1,qr); ret.f = (a.f*b.f)/(1-a.g*(1-b.f)); ret.g = b.g+(1-b.g)*a.g*b.f/(1+(b.f-1)*a.g); return ret; }}int main(){ freopen("E.in","r",stdin); freopen("E.out","w",stdout); scanf("%d %d",&N,&Q); for (int i = 1;i <= N;++i) A[i] = gi(),B[i] = gi(); build(1,1,N); while (Q--) { int opt = gi(); if (opt == 1) { int now = lef[gi()],a = gi(),b = gi(); f[now] = g[now] = (ld)a/(ld)b; for (now >>= 1;now;now >>= 1) { f[now] = (f[now<<1]*f[now<<1|1])/(1-g[now<<1]*(1-f[now<<1|1])); g[now] = g[now<<1|1]+(1-g[now<<1|1])*g[now<<1]*f[now<<1|1]/(1+(f[now<<1|1]-1)*g[now<<1]); } } else { int l = gi(),r = gi(); printf("%.10lf\n",(double)query(1,1,N,l,r).f); } } fclose(stdin); fclose(stdout); return 0;}

转载于:https://www.cnblogs.com/mmlz/p/5874822.html

你可能感兴趣的文章
Python接口自动化测试_悠悠
查看>>
(转)python学习笔记5--decimal
查看>>
[BZOJ 5323][Jxoi2018]游戏
查看>>
编程面试的10大算法概念汇总
查看>>
【蒟蒻周报】思维与结论的碰撞 9.17-9.23
查看>>
一个软件经历的阶段
查看>>
自我介绍
查看>>
毕业后第一份工作程序员应该做多久?
查看>>
Load generator连接失败的解决办法!(转)
查看>>
codevs 3295 落单的数
查看>>
演练:实现支持基于事件的异步模式的组件
查看>>
STM32 HAL库学习系列第7篇---定时器TIM 输入捕获功能
查看>>
PHP中file_get_contents函数获取带BOM的utf-8,然后json_decode() 返回null的问题
查看>>
SQLServer代理新建或者编辑作业报错
查看>>
LeetCode 搜索二维矩阵 II
查看>>
Python升级3.多
查看>>
算术表达式解析(第一版)
查看>>
java.lang.ClassNotFoundException: org.hibernate.annotations.common.reflection.MetadataProvider
查看>>
兼容各种浏览器的透明层效果
查看>>
软件工程概论课总结
查看>>