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. VWMare CentOS 6.5 静态IP设置

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGVmYXVsdDc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...

  2. win10常见问题-任务栏消失

    问题描写叙述: O疼地尝鲜了win10,bug层出不穷,眼下遇到的最大的两个BUG是: 1.启动后高概率出现黑屏,仅仅有鼠标,无桌面,无法拯救 2.正常执行高概率出现任务栏丢失现象.无法拯救 问题一, ...

  3. Strtus2标签之<s:url>

    Strtus2标签<s:url> 在没有使用Struts2的时候可以使用el来进行url传参.而在Struts2中不推荐使用el(其实在Struts2.0.0.11之后就不再支持el)而推 ...

  4. QuaZip实现多文件打包

    项目需求: 在Goldenfarm客户端中当用户选择了本地场景文件,并进行本地场景文件分析后会产生分析结果,分析结果主要包括:贴图纹理.可渲染层等,其中贴图纹理指出了在场景文件中使用到的贴图或其它文件 ...

  5. Day05 - Python 常用模块

    1. 模块简介 模块就是一个保存了 Python 代码的文件.模块能定义函数,类和变量.模块里也能包含可执行的代码. 模块也是 Python 对象,具有随机的名字属性用来绑定或引用. 下例是个简单的模 ...

  6. RedHat7 SELinux

    SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统.NSA是在Linux社区的帮助下开发了一种 ...

  7. Migration of ASP.NET app from IIS6 to IIS7 (7.5)

    For many of us familiar problem. You developing applications under IIS6 and you're about to move the ...

  8. Windows Python 2.7 安装 Numpy

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/4846093. ...

  9. PHP-popen()&nbsp;函数打开进程文件指针

    待更新 版权声明:本文为博主原创文章,未经博主允许不得转载.

  10. CI框架篇之预热篇(1)

    CodeIgniter 的基本都了解了,现在就开始预热,如果学习一门语言一样,我们最开始都是输出一个'HELLO WORLD'一样, 现在我们也通过输出这样一个内容,来了解基本的使用. CodeIgn ...