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. Linux下jvm、tomcat、mysql、log4j优化配置笔记[转]

    小菜一直对操作系统心存畏惧,以前也很少接触,这次创业购买了Linux云主机,由于木有人帮忙,只能自己动手优化服务器了.... 小菜的云主机配置大致为:centeos6(32位),4核心cpu,4G内存 ...

  2. JDBC Transaction Management Example---reference

    In this post, we want to talk about JDBC Transactions and how we can manage the operations in a data ...

  3. java注释 命名 数据类型 基本类型转换 位运算符 逻辑运算符 三目运算符

    一.java注释 1.单行注释  //注释内容 2.多行注释 /*注释内容*/ 3.文档注释(可用javadoc工具生成api文档,不过我还没试过)/**文档注释*/,文档注释可以在使用的时候看见注释 ...

  4. ThinkPHP的数据库访问的简单操作

    传统的sql与ThinkPHP中的sql相比较   以user表为例 $user=M('user'); 1: SELECT * FROM user----------$user->select( ...

  5. 20、CSS

    CSS 层叠样式表(Cascading Style Sheets). 用于定义显示HTML样式. DIV和SPAN div是块级元素. span是行级元素. 将一些页面中的内容包裹起来统一设置样式. ...

  6. 在Android上模拟登录广工正方教务系统查询成绩

    这是在博客园里开博以来写的第一篇博客. 因为之前看过很多人都有发过关于模拟登录正方软件获取数据的文章,自己觉得挺好玩的便也去动手一做,开始还以为挺难的,但实际做起来还蛮简单的,当然其中还有些小插曲. ...

  7. ROW_NUMBER () 与 PARTITION组合拳

    --在一个Book表里面里有字段AuthorID与Author表关联,现在要求按PublishDate字段倒序排列,列出每个作者的前五本书.要求有没有一条语句搞定的--可用游标或者临时表--最好解决方 ...

  8. 从source folder 下将其所有子文件夹的*.* 文件拷贝到 target folder (不拷贝文件夹名仅拷贝文件)

    因本人较懒,一直认为电脑能做的就让电脑来做,所以写下这个批处理的小脚本方便工作. 场景:碰到要拷贝一个文件夹(source folder)下的多个子文件夹(sub-folder)的文件到指定文件夹下( ...

  9. javascript-图片横向无缝隙滚动(可在服务器运行)

    前两次弄'图片横向滚动'javascript,在本地上运行得很美,可是一上到我们学校后台的服务器,就有很多问题,这个算是行的了. css代码: <style type="text/cs ...

  10. JavaScript中Ajax的get和post请求

    AJAX = 异步 JavaScript和XML(Asynchronous JavaScript and XML) 作用:在不重新加载整个网页的情况下,对网页的某部分进行更新.   两种请求方式: 1 ...