大佬教我做题
ans=∏i=LR(1−pi)=eln∏Ri=L(1−pi)=e∑Ri=Lln(1−pi) a n s = ∏ i = L R ( 1 − p i ) = e ln ∏ i = L R ( 1 − p i ) = e ∑ i = L R ln ( 1 − p i )
将
ln(1−x) ln ( 1 − x ) 泰勒展开
ln(1−x)=−∑i=1∞xii ln ( 1 − x ) = − ∑ i = 1 ∞ x i i
用线段树维护
x x 的前
100 100 次幂就可以了。
#include
using namespace std;
typedef double db;
const int N=100010;
const int M=99;
const db Eps=1e-7;
int k,n,m,x,y;
db t;
db a[N],c[N<<2][M],p[N<<2];
void Up(int x) {
for(int i=1;i1][i]+c[x<<1|1][i];
}
void Update_node(int x,db y) {
db t=1;
for(int i=1;ivoid Down(int x) {
if(p[x]==1) return;
Update_node(x<<1,p[x]);Update_node(x<<1|1,p[x]);
p[x]=1;
}
void Build(int x,int l,int r) {
p[x]=1;
if(l==r) {
c[x][1]=a[l];
for(int i=2;i1]*a[l];
return;
}
int Mid=l+r>>1;
Build(x<<1,l,Mid);Build(x<<1|1,Mid+1,r);
Up(x);
}
void Update(int x,int l,int r,int L,int R,db y) {
if(l>R||rreturn;
if(l>=L&&r<=R) {
Update_node(x,y);
return;
}
Down(x);
int Mid=l+r>>1;
Update(x<<1,l,Mid,L,R,y);Update(x<<1|1,Mid+1,r,L,R,y);
Up(x);
}
db Query(int x,int l,int r,int L,int R) {
if(l>R||rreturn 0;
if(l>=L&&r<=R) {
db Ans=0;
for(int i=1;ireturn Ans;
}
Down(x);
int Mid=l+r>>1;
return Query(x<<1,l,Mid,L,R)+Query(x<<1|1,Mid+1,r,L,R);
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lf",&a[i]);
Build(1,1,n);
while(m--) {
scanf("%d%d%d",&k,&x,&y);
if(!k) printf("%.7lf\n",exp(Query(1,1,n,x,y)));else scanf("%lf",&t),Update(1,1,n,x,y,t);
}
return 0;
}