一道线段树水题
注意别被卡精度(无时无刻都要想着强制转换double)
居然写了\(100min\),我太弱了!!!
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
const int N=1e5+4;
#define lc (p<<1)
#define rc (p<<1|1)
int n,m,a[N],b[N];
double t[N<<2],tx[N<<2],dx[N<<2],dy[N<<2],lzmx[N<<2],lzmy[N<<2],lzcx[N<<2],lzcy[N<<2];
double ans,anx,ax,ay;
inline void pushup(int p){
t[p]=t[lc]+t[rc];
tx[p]=tx[lc]+tx[rc];
dx[p]=dx[lc]+dx[rc];
dy[p]=dy[lc]+dy[rc];
}
inline void pushmo(int p,int l,int r,double x,double y){
t[p]+=dx[p]*y+dy[p]*x+x*y*(r-l+1);
tx[p]+=x*2*dx[p]+x*x*(r-l+1);
dx[p]+=x*(r-l+1);
dy[p]+=y*(r-l+1);
lzmx[p]+=x;
lzmy[p]+=y;
}
inline double ii(double x){
return x*(x+1)*(x*2+1)/6;
}
inline void pushco(int p,int l,int r,double x,double y){
lzmx[p]=lzmy[p]=0;
t[p]=ii(r)-ii(l-1)+(x+y)*(l+r)*(r-l+1)/2+x*y*(r-l+1);
tx[p]=ii(r)-ii(l-1)+x*2*(l+r)*(r-l+1)/2+x*x*(r-l+1);
dx[p]=x*(r-l+1)+(double)(l+r)*(r-l+1)/2;//double
dy[p]=y*(r-l+1)+(double)(l+r)*(r-l+1)/2;
lzcx[p]=x;lzcy[p]=y;
}
inline void pushdown(int p,int l,int mid,int r){
if(lzcx[p]||lzcy[p]){
pushco(lc,l,mid,lzcx[p],lzcy[p]);
pushco(rc,mid+1,r,lzcx[p],lzcy[p]);
lzcx[p]=lzcy[p]=0;
}
if(lzmx[p]||lzmy[p]){
pushmo(lc,l,mid,lzmx[p],lzmy[p]);
pushmo(rc,mid+1,r,lzmx[p],lzmy[p]);
lzmx[p]=lzmy[p]=0;
}
}
inline void build(int p,int l,int r){
if(l==r){
t[p]=(double)a[l]*b[l];
tx[p]=(double)a[l]*a[l];
dx[p]=a[l];
dy[p]=b[l];
return;
}
int mid=(l+r)>>1;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(p);
}
inline void modify(int p,int l,int r,int ql,int qr,double x,double y){
if(ql<=l&&r<=qr){
pushmo(p,l,r,x,y);
return;
}
int mid=l+r>>1;
pushdown(p,l,mid,r);
if(ql<=mid)modify(lc,l,mid,ql,qr,x,y);
if(mid<qr)modify(rc,mid+1,r,ql,qr,x,y);
pushup(p);
}
inline void cover(int p,int l,int r,int ql,int qr,double x,double y){
if(ql<=l&&r<=qr){
pushco(p,l,r,x,y);
return;
}
int mid=l+r>>1;
pushdown(p,l,mid,r);
if(ql<=mid)cover(lc,l,mid,ql,qr,x,y);
if(mid<qr)cover(rc,mid+1,r,ql,qr,x,y);
pushup(p);
}
inline void query(int p,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){
ans+=t[p];
anx+=tx[p];
ax+=dx[p];
ay+=dy[p];
return;
}
int mid=l+r>>1;
pushdown(p,l,mid,r);
if(ql<=mid)query(lc,l,mid,ql,qr);
if(mid<qr)query(rc,mid+1,r,ql,qr);
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)b[i]=read();
build(1,1,n);
while(m--){
static int op,l,r,x,y;
op=read();l=read();r=read();
if(op==1){
ans=anx=ax=ay=0;
query(1,1,n,l,r);
l=r-l+1;
printf("%.8lf\n",(ans-ax*ay/l)/(anx-ax*ax/l));
continue;
}
x=read();y=read();
if(op==2)modify(1,1,n,l,r,x,y);
else cover(1,1,n,l,r,x,y);
}
return (0-0);
}