設\(f[i]\)爲從\(i\)到\(r+1\)且不走出區間的機率ios
\(f[i]=p[i]f[i+1]+(1-p[i])f[i-1]\)ui
\(f[i]-f[i-1]=p[i](f[i+1]-f[i-1])\)spa
\(f[r+1]=1,f[l-1]=0\)code
\(g[i]=f[i]-f[i-1]\)get
\(g[i]=p[i](g[i+1]+g[i])\)string
\(g[i+1]=\frac{1-p[i]}{p[i]} g[i]\)it
\(\sum_{i=l}^{r+1} g[i]=f[r+1]-f[l-1]=1\)io
\(lis[l][r]=\sum_{i=l}^{r} \prod_{j=l}^i \frac{1-p[j]}{p[j]}\)class
\(f[l]=g[l]=\frac{1}{lis[l][r]+1}\)stream
線段樹維護前綴積、前綴和便可
#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\n",1.0/(cask(1,1,n,l,r).b+1));} }return 0; }