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<iostream>
#include<cstdio>
#include<cstdlib>
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;
}

Codeforces 712E Memory and Casinos的更多相关文章

  1. cf 712E Memory and Casinos

    题意:有一行$n(n \leq 100000)$个方格,从左往右第$i$个方格的值为$p_i(p_i = \frac{a}{b}, 1 \leq a < b \leq 1e9)$,有两种操作,一 ...

  2. Codeforces Round #370 (Div. 2) E. Memory and Casinos 线段树

    E. Memory and Casinos 题目连接: http://codeforces.com/contest/712/problem/E Description There are n casi ...

  3. Memory and Casinos CodeForces - 712E (概率,线段树)

    题目链接 题目大意:$n$个点, 每个点$i$有成功率$p_i$, 若成功走到$i+1$, 否则走到走到$i-1$, 多组询问, 求从$l$出发, 在$l$处不失败, 最后在$r$处胜利的概率 设$L ...

  4. Codeforces Round #370 (Div. 2) E. Memory and Casinos (数学&&概率&&线段树)

    题目链接: http://codeforces.com/contest/712/problem/E 题目大意: 一条直线上有n格,在第i格有pi的可能性向右走一格,1-pi的可能性向左走一格,有2中操 ...

  5. codeforces 712B. Memory and Trident

    题目链接:http://codeforces.com/problemset/problem/712/B 题目大意: 给出一个字符串(由'U''D''L''R'),分别是向上.向下.向左.向右一个单位, ...

  6. codeforces 712A. Memory and Crow

    题目链接:http://codeforces.com/problemset/problem/712/A 题目大意: 给你一个数字系列,求其满足条件的一个序列. 条件为: ai = bi - bi +  ...

  7. Codeforces 712C Memory and De-Evolution

    Description Memory is now interested in the de-evolution of objects, specifically triangles. He star ...

  8. [CodeForces - 712D]Memory and Scores (DP 或者 生成函数)

    题目大意: 两个人玩取数游戏,第一个人分数一开始是a,第二个分数一开始是b,接下来t轮,每轮两人都选择一个[-k,k]范围内的整数,加到自己的分数里,求有多少种情况使得t轮结束后a的分数比b高.  ( ...

  9. CodeForces 712D Memory and Scores

    $dp$,前缀和. 记$dp[i][j]$表示$i$轮结束之后,两人差值为$j$的方案数. 转移很容易想到,但是转移的复杂度是$O(2*k)$的,需要优化,观察一下可以发现可以用过前缀和来优化. 我把 ...

随机推荐

  1. Android菜单详解(四)——使用上下文菜单ContextMenu

    之前在<Android菜单详解(二)——创建并响应选项菜单>和<Android菜单详解(三)——SubMenu和IconMenu>中详细讲解了选项菜单,子菜单和图标菜单.今天接 ...

  2. RAID 2.0

      传统的RAID 1.0: 选几个硬盘—>做成RAID 5—>根据容量创建LUN—>映射给主机 1.重建时间随单盘容量的增大而迅速增加 2.性能上,一个LUN的读写只能在一个磁盘组 ...

  3. servlet和手动创建servlet,断点调试

    1.    什么是Servlet Servlet是一种用Java语言编写的Web应用组件 Servlet主要用于动态网页输出,扩展了Web服务器的功能 Servlet由Servlet容器进行管理 2. ...

  4. Java基础知识强化之集合框架笔记60:Map集合之TreeMap(TreeMap<Student,String>)的案例

    1. TreeMap(TreeMap<Student,String>)的案例 2. 案例代码: (1)Student.java: package cn.itcast_04; public ...

  5. 最近有机会接触到了angularJs

    记点笔记  概念多了 理顺还待时日: 总的来说: 1.ng-src src属性 2.ng-href href属性 3.ng-checked 选中状态 4.ng-selected 被选择状态 5.ng- ...

  6. CI框架篇之模型篇--初识(1)

    模型 模型是专门用来和数据库打交道的PHP类.例如,假设你想用CodeIgniter来做一个Blog. 你可以写一个模型类,里面包含插入.更新.删除Blog数据的方法. 下面的例子将向你展示一个普通的 ...

  7. DataGrid列的合并

    /// <summary> /// DataGrid列的合并 /// 注意:1.DataGrid在绑定的时候进行分组和排序,才能让相同的行放在一起 /// 2.方法应用的时机,应该在Dat ...

  8. 网页Gzip

    网页Gzip压缩检测工具 网站Gzip压缩可以减小服务器带宽占用,提高用户打开网页速度,最多可以提升网站80%的性能,是每个网站必须开启的功能, 站长工具网页 Gzip压缩检测工具方便站长朋友们检测特 ...

  9. android系统体系结构

    android系统底层是建立在Linux系统之上的,如下图 从上图可以看出android系统有五部分组成 1.APPLICATIONS(应用程序层) 包含一些核心应用程序,电子邮件,日历,地图,浏览器 ...

  10. AndroidStudio1.4 manifest 中注册Activity时的错误提示解决办法

    问题截图如下: 解决办法截图如下: 1: File->setting->Editor->Language Injections到如下界面 2:双击右侧选中的Item进入编辑界面 3: ...