传送门 here

题意:

有n个赌场,第i个赌场的胜率为$ P_i$,在第i个赌场若取胜则到达第$ i+1$个赌场,反之到达第$ i-1$个赌场

定义统治赌场$ L...R$为从赌场$ L$开始,从赌场$ R+1$结束且期间没有到达过$ L$前面的赌场(没有在赌场$ L$输过)

有$ q$次操作,修改一个赌场的胜率或者询问统治赌场$ L...R$的概率

这题真的很妙啊...

我们定义$ f(i)$为从i走到目标地点的概率

显然当询问$ L...R$时有$ f(L-1)=0,f(R+1)=1$

根据题意有$ f(i)=P_if(i+1)+(1-P_i)f(i-1)$

移项得$ f(i)-f(i-1)=P_if(i+1)+(1-1-P_i)f(i-1)=P_i(f(i+1)-f(i-1))$

定义$ g(i)=f(i)-f(i-1)$

则有$ g(i)=P_i(f(i+1)-f(i-1))$

容易发现$ g(L)=f(L)$也就是所要求的答案

计算$ g(i+1)+g(i)=f(i+1)-f(i)+f(i)-f(i-1)=f(i+1)-f(i-1)=\frac{1}{P_i}g(i)$

因而有$ g(i+1)=\frac{1-P_i}{P_i}g(i)$

根据g的定义有$ \sum\limits_{i=L}^Rg(i)=f(R+1)-f(L-1)=1$

我们又知道$ g(i+1)$和$ g(i)$的比值关系,设为$ t_i$

则有$ g(L)*(1+t_L+t_Lt_{L+1}+...+t_{L}*...*t_{R})=1$

就可以用线段树维护t的信息计算结果了

由于只需要四位精度,因此当括号内的数超过$ 10000$即可跳出避免爆double

my code:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rt register int
#define ll long long
#define r read()
using namespace std;
ll read()
{
ll x = ; int zf = ; char ch;
while (ch != '-' && (ch < '' || ch > '')) ch = getchar();
if (ch == '-') zf = -, ch = getchar();
while (ch >= '' && ch <= '') x = x * + ch - '', ch = getchar(); return x * zf;
}
int i,j,k,m,n,x,y,z,cnt,all,num;
double p[],val[],qz[];
struct segment_tree{
int L,R;double val,ji;
}a[];
void build(const int x,const int L,const int R)
{
a[x].L=L;a[x].R=R;
if(L==R)
{
a[x].val=a[x].ji=val[L];
return;
}
const int mid=L+R>>;
build(x<<,L,mid);build(x<<|,mid+,R);
a[x].val=a[x<<].val+a[x<<|].val*a[x<<].ji;
a[x].ji=a[x<<].ji*a[x<<|].ji;
}
void change(const int x,const int L,const double val)
{
if(a[x].L==a[x].R)
{
a[x].val=a[x].ji=val;
return;
}
L<=a[x].L+a[x].R>>?change(x<<,L,val):change(x<<|,L,val);
a[x].val=a[x<<].val+a[x<<|].val*a[x<<].ji;
a[x].ji=a[x<<].ji*a[x<<|].ji;
}
double ansa,ansb;
void query(const int x,const int L,const int R)
{
if(ansa>)return;
if(a[x].L>R||a[x].R<L)return;
if(a[x].L>=L&&a[x].R<=R)
{
ansa+=a[x].val*ansb;
ansb*=a[x].ji;
return;
}
query(x<<,L,R);query(x<<|,L,R);
}
int main()
{
n=r;m=r;
for(rt i=;i<=n;i++)
{
x=r;y=r;
p[i]=(double)x/(double)y;
val[i]=(-p[i])/p[i];
}
build(,,n);
while(m--)
{
int opt=r;
if(opt==)
{
int L=r,R=r;ansa=;ansb=;query(,L,R);
printf("%.6f\n",/(ansa+));
}
else
{
int L=r;x=r;y=r;
double t=(double)x/(double)y;
change(,L,(-t)/t);
p[L]=t;
}
}
return ;
}

Codeforces712E的更多相关文章

随机推荐

  1. JavaScript frame跨域获取元素、修改元素属性、调用其他frame页面方法

    今天做了一个frameset的集合页面,其中有多个iframe页面,其中点击frame=leftMenu里的按钮元素后,需要修改frame=Header页面里的一个div元素属性. 1.主页面架构 & ...

  2. Mock1 moco框架的基本介绍

    前言: Mock就是模拟接口的,一般在开发人员还没有开发完接口,但是有接口文档,这个时候就可以执行接口测试,前端同学也可以用mock功能给自己使用. 功能:可以模拟http协议发送请求 下载链接:ht ...

  3. ElasticSearch6.5.0 【字段类型】

    字符串类型 text 适合全文索引,有分析的过程 keyword 适合结构化的数据,比如地址.电话号码... 数字 long [带符号64位整数]范围:-263 ~ 263-1 integer     ...

  4. 转:upload.parseRequest为空

    上传是items一直是空list.导致原因是struts2把原始的原来S2为简化上传功能,把所有的enctype="multipart/form-data"表单做了wrapper最 ...

  5. java equals和hashcode方法

    equals()方法比较两个对象的引用是否相同 hashcode()方法比较两个对象的哈希码是否相同

  6. 数据挖掘的标准流程-CRISP-DM

    1.起源 CRISP-DM (cross-industry standard process for data mining), 即为"跨行业数据挖掘过程标准".此KDD(know ...

  7. 机器学习-随机梯度下降(Stochastic gradient descent)

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...

  8. OS + Linux RedHat 7 / redhat 7 configuration

    s redhat 7.2 tracker-store CPU消耗高的问题 http://www.cnblogs.com/exiahan/archive/2013/07/08/3177971.html ...

  9. rsync 文件同步(差异复制)

    Rsync 是一种快速且极其通用的文件复制工具.以其 Delta 传输算法,通过仅发送源文件和目标中现有文件之间的差异来减少通过网络发送的数据量 Rsync 的几种复制方式:Local,SSH 和 R ...

  10. JAVA核心技术I---JAVA基础知识(多态)

    一:类转型 类转型:子类可以转父类,父类不可以转子类(除非父类对象本身就是子类) 1.父类 public class Human { public void say() { System.out.pr ...