【CF712E】Memory and Casinos(数学 期望 DP)
大意
给出一个序列,当你在某个点时,有一个向右走的概率\(P_i\)(向左为\(1-P_i\)),
给出\(M\)个操作,操作有两类:
1 X Y Z:把\(P_X\)的值修改为\(\frac{Y}{Z}\)
2 L R:询问你从\(L\)出发,随机游走,在不经过\(L-1\)的情况下到达\(R+1\)的概率
思路
我们对于一个区间设有两个值\(ValL,ValR\),
分别表示从这段区间的左端点出发能赢的概率与从它的右端点出发能赢的概率。
即我们要求的是任意区间的\(ValL\).
考虑一个区间的\(Val\)如何从它的两个子区间转移而来。
首先对于\(ValL\)
肯定有一个\(S1.ValL\times S2.ValL\),表示从\(S1\)的左端点出发到达\(S2\)左端点,再到\(R+1\),但是明显会漏掉在\(S1,S2\)间反复横跳的情况。
我们不妨枚举一下它横跳的次数来计算
\]
化简为$$\frac{1}{1-S1.ValR\times (1-S2.ValL)}$$
即$$ValL=\frac{S1.ValL\times S2.ValL}{1-S1.ValR\times (1-S2.ValL)}$$
同理,对于\(ValR\),也有横跳的情况,但向左向右横跳的次数就有差距了。
\]
化简为$$\frac{(1-S2.ValR)\times S2.ValL\times S1.ValR}{1-S1.ValR\times (1-S2.ValL)}$$
同时,\(ValR\)也有不横跳的情况,即\(S2.ValR\).
综合一下
\]
对于ValL与ValR,可以使用线段树维护。
代码
没打重载,暴力合并
#include<cstdio>
#include<algorithm>
using namespace std;
#define fi first
#define se second
const double ONE=1.0;
const int MAXN=100005;
const int INF=0X3F3F3F3F;
int N,Q;
double P[MAXN];
struct Node{
int l,r;pair<double,double>val;
}s[MAXN*8];
void Push_Up(int rt){
pair<double,double>ret1=s[rt*2].val,ret2=s[rt*2+1].val;
s[rt].val.fi=ret1.fi*ret2.fi/(1-ret1.se*(1-ret2.fi));
s[rt].val.se=ret2.se+(1-ret2.se)*ret2.fi*ret1.se/(1-ret1.se*(1-ret2.fi));
}
void Build(int rt,int l,int r){
s[rt].l=l;s[rt].r=r;
s[rt].val.fi=s[rt].val.se=-INF;
if(l==r){
s[rt].val.fi=P[l];
s[rt].val.se=P[l];
return ;
}
int mid=(l+r)/2;
Build(rt*2,l,mid);
Build(rt*2+1,mid+1,r);
Push_Up(rt);
}
void Insert(int rt,int p,double val){
if(s[rt].l>p||s[rt].r<p)return ;
if(s[rt].l==s[rt].r){s[rt].val.fi=s[rt].val.se=val;return ;}
Insert(rt*2,p,val);Insert(rt*2+1,p,val);Push_Up(rt);
}
pair<double,double>Query(int rt,int l,int r){
pair<double,double>ret;ret.fi=ret.se=-INF;
if(s[rt].l>r||s[rt].r<l)return ret;
if(s[rt].l>=l&&s[rt].r<=r)return s[rt].val;
pair<double,double>ret1,ret2;
ret1=Query(rt*2,l,r);
ret2=Query(rt*2+1,l,r);
if(ret1.fi==-INF&&ret2.fi==-INF)return ret;
if(ret1.fi==-INF)ret=ret2;
else if(ret2.fi==-INF)ret=ret1;
else{
ret.fi=ret1.fi*ret2.fi/(1-ret1.se*(1-ret2.fi));
ret.se=ret2.se+(1-ret2.se)*ret2.fi*ret1.se/(1-ret1.se*(1-ret2.fi));
}
return ret;
}
int main(){
scanf("%d%d",&N,&Q);
for(int i=1,A,B;i<=N;i++){
scanf("%d%d",&A,&B);
P[i]=ONE*A/B;
}
Build(1,1,N);
for(int i=1,k,x,y,z;i<=Q;i++){
scanf("%d%d%d",&k,&x,&y);
if(k==1){
scanf("%d",&z);
Insert(1,x,ONE*y/z);
}
if(k==2)printf("%.10f\n",Query(1,x,y).fi);
}
return 0;
}
【CF712E】Memory and Casinos(数学 期望 DP)的更多相关文章
- codeforces1097D Makoto and a Blackboard 数学+期望dp
题目传送门 题目大意: 给出一个n和k,每次操作可以把n等概率的变成自己的某一个因数,(6可以变成1,2,3,6,并且概率相等),问经过k次操作后,期望是多少? 思路:数学和期望dp 好题好题!! ...
- lightoj1038(数学期望dp)
题意:输入一个数N,N每次被它的任意一个因数所除 变成新的N 这样一直除下去 直到 N变为1 求变成1所期望的次数 解析: d[i] 代表从i除到1的期望步数:那么假设i一共有c个因子(包括1和本身) ...
- 【BZOJ4872】[Shoi2017]分手是祝愿 数学+期望DP
[BZOJ4872][Shoi2017]分手是祝愿 Description Zeit und Raum trennen dich und mich. 时空将你我分开.B 君在玩一个游戏,这个游戏由 n ...
- BZOJ 1426: 收集邮票 数学期望 + DP
Description 有n种不同的邮票,皮皮想收集所有种类的邮票.唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且 买到的邮票究竟是n种邮票中的哪一种是等概率的,概率均为1/n.但是由于凡凡 ...
- CF712E Memory and Casinos 期望概率
题意:\(n\)个赌场,每个赌场有\(p_{i}\)的胜率,如果赢了就走到下一个赌场,输了就退回上一个赌场,规定\(1\)号赌场的上一个是\(0\)号赌场,\(n\)号赌场的下一个是\(n + 1\) ...
- CF708E-Student‘s Camp【数学期望,dp】
正题 题目链接:https://www.luogu.com.cn/problem/CF708E 题目大意 有\(n*m\)的矩形网格,然后每次每行最左边和最右边的格子各有\(p=\frac{c}{d} ...
- Codeforces Round #370 (Div. 2) E. Memory and Casinos (数学&&概率&&线段树)
题目链接: http://codeforces.com/contest/712/problem/E 题目大意: 一条直线上有n格,在第i格有pi的可能性向右走一格,1-pi的可能性向左走一格,有2中操 ...
- CF712E Memory and Casinos
设\(f[i]\)为从\(i\)到\(r+1\)且不走出区间的概率 \(f[i]=p[i]f[i+1]+(1-p[i])f[i-1]\) \(f[i]-f[i-1]=p[i](f[i+1]-f[i-1 ...
- [题解]数学期望_luogu_P1850_换教室
数学期望dp,题面第一次见很吓人,然而从CCF语翻译成人话就简单多了, 开始一般会想到用 f [ i ] [ j ]表示前 i 个课程申请 j 次的期望,然而其实会发现转移的时候还和上一次的情况有关( ...
随机推荐
- Selenium_使用switch_to.frame处理网页框架切换(13)
与在新窗口打开一个网页后需要切换窗口才能定位元素一样,在iframe标签中的元素也不能直接定位,需要切换到对应的iframe框架中才能进行元素定位. 完成网页框架切换操作需要用selenium中的两个 ...
- 在quasar 注册全局filter
A common use case for Quasar applications is to run code before the root Vue app instance is instant ...
- 单篇长文TestNG从入门到精通
简介 TestNG是Test Next Generation的缩写,它的灵感来自于JUnit和NUnit,在它们基础上增加了很多很牛的功能,比如说: 注解. 多线程,比如所有方法都在各自线程中,一个测 ...
- k8s的应用包管理工具helm的部署和使用
1.概述 我们一般是在k8s里面部署一些简单的应用,比如用deployment,daemonset,statefuleset的方式来部署应用,但是如果要部署一些复杂的应用,那么整个配置的编写.部署的过 ...
- github与gitlab创建新仓库
github创建新仓库 然后根据下一页的命令提示进行即可 gitlab创建新仓库 git init git remote add origin git@***.***.**.**:user/proje ...
- JavaScript DOM 基础操作
JavaScript DOM 基础操作 一.获取元素的六方式 document.getElementById('id名称') //根据id名称获取 document.getElementsByclas ...
- 第56篇-ProfileData与DataLayout
某些指令需要创建某些实例,如下: 指令 对应的DataLayout._struct._tag值 _checkcast._instanceof._aastore receiver_type_data_t ...
- 【C++】自定义数据类型
自定义数据类型 标签:c++ 目录 自定义数据类型 一.结构体 定义方法: 特点: 成员访问方式: 初始化: 结构数组 指针和动态内存分配: 结构变量作为函数参数: 二.联合 定义方法: 特点: 举例 ...
- 【刷题-PAT】A1101 Quick Sort (25 分)
1101 Quick Sort (25 分) There is a classical process named partition in the famous quick sort algorit ...
- C++类对象大小问题(一)
先看如下代码: #include<iostream> using namespace std; class Base1 { public: }; class Base2 { public: ...