Codeforces Round #370 (Div. 2) E. Memory and Casinos
来源:互联网 发布:金手指手机炒股软件 编辑:程序博客网 时间:2024/05/17 00:12
E. Memory and Casinos
time limit per test4 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
There are n casinos lined in a row. If Memory plays at casino i, he has probability pi to win and move to the casino on the right (i + 1) or exit the row (if i = n), and a probability 1 - pi 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… j if he completes a walk such that,
He starts on casino i.
He never looses in casino i.
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 .
2 l r: Print the probability that Memory will dominate on the interval l… r, i.e. compute the probability that Memory will first leave the segment l… 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. pi ≤ pi + 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 ≤ n, q ≤ 100 000), — number of casinos and number of requests respectively.
The next n lines each contain integers ai and bi (1 ≤ ai < bi ≤ 109) — is the probability pi 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 |a - b| ≤ 10 - 4.
Example
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
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
题意:给出n个的赌场,和每个赌场的胜率,胜利前进一格,否则退回一格,问从l出发,第一次走出l,r是从r出去的概率。
用线段树维护区间l,r从l出发,l走出去的概率pl,r走出去的概率pr,和从r出发,从l走出去的概率rpl,从r走出去的概率rpr,区间合并公式:已知l1,r1和l2,r2,r1+1=l2,求区间l1,r2;
pr(l1,r2) = pr(l1,r1)pr(l2,r2)(1/(rpr(l1,r1)*pl(l2,r2));
rpl(l1,r2) = rpl(l1,r1)rpl(l2,r2)(1/(rpr(l1,l2)*pl(l2,r2));
证明1:点与他前面的区间合并,
已知l,r,从l出去,r走出去的概率为pr,l-1的胜率为px,则第一次从l-1走到l,有pr从r出去,pl走回l-1,然后走回l-1的点还会对结果做出贡献,然后下一次的贡献是走到l-1,又走到r的部分,每次走到l位置都会对结果做出一部分贡献,可以观察出每次走到l位置的概率是等比数列,所以可以求出l-1走到r的概率,
证明2:区间与区间合并
区间合并的时候要维护两个值,从左端出发,和从右端出发,根据证明1;模拟一下,就可以理解证明2了;
#include<bits/stdc++.h>#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;const int N= 1e5+100;const int B = 333;struct node{ double pl,pr; double rpl,rpr;};node sum[N<<2];int a[N],b[N];int n,q;node solve(node a,node b){ node now; now.pr = a.pr/(1-a.rpr*b.pl)*b.pr; now.pl = 1 - now.pr; now.rpl = b.rpl/(1-a.rpr*b.pl)*a.rpl; now.rpr = 1 - now.rpl; return now;}void pushup(int rt){ sum[rt] = solve(sum[rt<<1],sum[rt<<1|1]);}void build(int l,int r,int rt){ if(l == r){ double now = a[l]*1.0/b[l]; sum[rt].pl = 1-now; sum[rt].pr = now; sum[rt].rpl = 1-now; sum[rt].rpr = now; //cout<< l << ' '<< r << ' ' << rt << ' '<< sum[rt].pr<<endl; return ; } int mid = (l+r)>>1; build(lson); build(rson); pushup(rt); //cout <<l << ' '<< r << ' '<< rt << ' '<< sum[rt].pr << ' '<<sum[rt].rpl << endl;}node query(int L,int R,int l,int r,int rt){ if(L <= l && R >= r){ return sum[rt]; } int mid = (l+r)>>1; node now{0,1}; if(mid < R) now = query(L,R,rson); if(mid >= L) now = solve(query(L,R,lson),now); return now;}void update(int x,double f,int l,int r,int rt){ if(l == r){ sum[rt].pr = f; sum[rt].pl = 1-f; sum[rt].rpr = f; sum[rt].rpl = 1-f; return; } int mid = (l+r)>>1; if(mid >= x) update(x,f,lson); else update(x,f,rson); pushup(rt);}int main(){ scanf("%d %d",&n,&q); for(int i = 1;i <= n;i ++){ scanf("%d %d",&a[i],&b[i]); } build(1,n,1); node a = sum[4],b = sum[5],c = sum[3]; node now = solve(b,c); now = solve(a,now); //cout << now.pr <<' ' << now.pl << endl; for(int i= 1;i <= q;i ++){ int op; scanf("%d",&op); if(op == 1){ int x,a,b; scanf("%d %d %d",&x,&a,&b); update(x,a*1.0/b,1,n,1); } else { int l,r; scanf("%d %d",&l,&r); node ans = query(l,r,1,n,1); printf("%.10f\n",ans.pr); } } return 0;}
- Codeforces Round #370 (Div. 2) E. Memory and Casinos
- Codeforces Round #370 (Div. 2) E. Memory and Casinos 线段树
- 【Codeforces Round 370 (Div 2) E】【线段树 等比数列 区间合并】Memory and Casinos 赌场区间[l,r] l进r先出的概率
- Codeforces 712E Memory And Casinos 概率+线段树
- Codeforces Round #370 (Div. 2)-C. Memory and De-Evolution
- 【Codeforces Round 370 (Div 2) A】【水题】Memory and Crow
- Codeforces Round #370 (Div. 2) C. Memory and De-Evolution
- Codeforces Round #370 (Div. 2) D. Memory and Scores
- [Codeforces 712E Memory and Casinos]概率+线段树区间合并
- Codeforces 852 E Casinos and travel [想法]
- Codeforces Round #167 (Div. 2) 272E Dima and Horses
- Codeforces Round #206 (Div. 2) E. Vasya and Beautiful Arrays
- Codeforces Round #208 (Div. 2)E. Dima and Kicks
- Codeforces Round #199 (Div. 2) E. Xenia and Tree
- Codeforces Round #224 (Div. 2) E.Ksenia and Combinatorics
- Codeforces Round #261 (Div. 2) E. Pashmak and Graph
- Codeforces Round #261 (Div. 2) E. Pashmak and Graph【DP】
- Codeforces Round #261 (Div. 2) E. Pashmak and Graph DP
- 深入理解JVM(四)——对象内存的分配策略
- c++ 宏要点;
- Linux文件管理常用命令
- Oracle常用批量操作
- 利用Oracle闪回技术恢复误操作数据
- Codeforces Round #370 (Div. 2) E. Memory and Casinos
- 数据库导出表格式到excel
- 深度学习笔记——理论与推导之Structured Learning【Structured SVM】(七)
- thinkphp mysql 读写分离
- SQL Server数据同步
- 搜索数据库存储过程或者函数中的内容
- 要将PDF文档进行文字排版需要使用什么PDF编辑软件
- p5.js入门教程(4) 鼠标交互
- PopupWindow悬浮框