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. activity中实现Spinner绑定

    (1)须要一个基本的布局文件activity_main <RelativeLayout xmlns:android="http://schemas.android.com/apk/re ...

  2. 聊一聊 Android 6.0 的运行时权限

    权限一刀切 棉花糖运行时权限 权限的分组 正常权限 正常权限列表 特殊权限危险权限 请求SYSTEM_ALERT_WINDOW 请求WRITE_SETTINGS 必须要支持运行时权限么 不支持运行时权 ...

  3. MYSQL 5.7 MTS 复制

    http://www.linuxidc.com/Linux/2013-04/82712p2.htm http://keithlan.github.io/2016/06/28/MTS/ http://d ...

  4. pip安装 MySQLDb 和 Django

    wget "https://pypi.python.org/packages/source/p/pip/pip-1.5.4.tar.gz#md5=834b2904f92d46aaa33326 ...

  5. LabVIEW设计模式系列——资源关闭后错误处理

    标准: 1.很多引用资源其打开函数和关闭函数对错误处理的方式有所不同:2.一般地NI的Help里对打开函数的错误端子的解释是这样的:如错误发生在VI或函数运行之前,VI或函数将把错误输入值传递至错误输 ...

  6. Cocopods -第三方库的管理

    前言 什么是CocoaPods? CocoaPods是OS X和iOS下的一个第三类库管理工具,通过CocoaPods工具我们可以为项目添加被称为“Pods”的依赖库(这些类库必须是CocoaPods ...

  7. HTTP基础:URL格式、 HTTP请求、响应、消息

    HTTP URL 格式: http://host[:port][abs_path] 其中http表示要通过HTTP协议来定位网络资源. host表示合法的Internet主机域名或IP地址(以点分十进 ...

  8. 借鉴网上的winform模仿QQ窗口停靠功能稍作改动

    2015-07-11 15:24:04 1 using System; using System.Collections.Generic; using System.ComponentModel; u ...

  9. php之常量小见

    php设置常量有二种方法,一为define(),二为使用关键字const. define()函数带有三个形参,一为常量名,通常以大写字母命名,二为值,三为是否对大小写敏感,其值为可选,默认为false ...

  10. final----这篇文章是我收获很大

    final 用于声明属性.方法和类,分别表示属性不可变,方法不可重写,类不可继承. [转]Java final 修饰符知识点总结 final从字面上理解含义为“最后的,最终的”.在Java中也同样表示 ...