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]))

(f[r+1]=1,f[l-1]=0)

(g[i]=f[i]-f[i-1])

(g[i]=p[i](g[i+1]+g[i]))

(g[i+1]=frac{1-p[i]}{p[i]} g[i])

(sum_{i=l}^{r+1} g[i]=f[r+1]-f[l-1]=1)

(lis[l][r]=sum_{i=l}^{r} prod_{j=l}^i frac{1-p[j]}{p[j]})

(f[l]=g[l]=frac{1}{lis[l][r]+1})

线段树维护前缀积、前缀和即可

#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;

const int MAXN=1<<17;

int n,m;
int ik[MAXN];
double sum[2][MAXN<<1];
struct rpg{double a,b;};

int read()
{
	int x=0;char ch=getchar();
	while(ch<'0'||'9'<ch) ch=getchar();
	while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x;
}

void build(int k,int l,int r)
{
	if(l==r){ik[l]=k;return;}
	int i=k<<1,mid=l+r>>1;
	build(i,l,mid),build(i|1,mid+1,r);
	return;
}

void cchg(int k,double v)
{
	sum[0][k]=sum[1][k]=v;k>>=1;
	while(k){
		int i=k<<1;
		sum[0][k]=sum[0][i]*sum[0][i|1];
		sum[1][k]=sum[1][i]+sum[0][i]*sum[1][i|1];
		k>>=1;
	}return;
}

rpg cask(int k,int l,int r,int le,int ri)
{
	if(le<=l&&r<=ri) return (rpg){sum[0][k],sum[1][k]};
	int i=k<<1,mid=l+r>>1;
	if(le<=mid&&mid<ri){
		rpg sum=cask(i,l,mid,le,ri),tmp=cask(i|1,mid+1,r,le,ri);
		sum.b+=sum.a*tmp.b;
		sum.a*=tmp.a;
		return sum;
	}if(le<=mid) return cask(i,l,mid,le,ri);
	return cask(i|1,mid+1,r,le,ri);
}

int main()
{
	n=read();m=read();
	build(1,1,n);
	for(int i=1;i<=n;++i){
		int a=read(),b=read();
		double f=1.0*a/b;
		cchg(ik[i],(1.0-f)/f);
	}while(m--){
		int p=read();
		if(p==1){int k=read(),a=read(),b=read();double f=1.0*a/b;cchg(ik[k],(1.0-f)/f);}
		else{int l=read(),r=read();printf("%.10lf
",1.0/(cask(1,1,n,l,r).b+1));}
	}return 0;
}
原文地址:https://www.cnblogs.com/AH2002/p/10297729.html