题解:线段树
3操作的l,r没赋初始值竟然过了样例???
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#define lo now<<1
#define ro now<<1|1
using namespace std;
const int maxn=100009;
int n,m;
double inx[maxn],iny[maxn];
double si[maxn],si2[maxn];
struct SegmentTree{
int l,r;
double x,y,xy,xx;
double stx,sty,hst;
double tagx,tagy,htag;
}tree[maxn<<2];
void pushup(int now){
tree[now].x=tree[lo].x+tree[ro].x;
tree[now].y=tree[lo].y+tree[ro].y;
tree[now].xy=tree[lo].xy+tree[ro].xy;
tree[now].xx=tree[lo].xx+tree[ro].xx;
}
void pushdown(int now){
int son;
double stx=tree[now].stx;
double sty=tree[now].sty;
double tagx=tree[now].tagx;
double tagy=tree[now].tagy;
double x,y,xy,xx;
int l,r;
for(int i=0;i<=1;++i){
son=(now<<1|i);
l=tree[son].l;
r=tree[son].r;
if(tree[now].hst){
tree[son].stx=stx;
tree[son].sty=sty;
tree[son].hst=1;
tree[son].tagx=0;
tree[son].tagy=0;
tree[son].htag=0;
tree[son].x=(r-l+1)*stx+(si[r]-si[l-1]);
tree[son].y=(r-l+1)*sty+(si[r]-si[l-1]);
tree[son].xy=(r-l+1)*stx*sty+(stx+sty)*(si[r]-si[l-1])+(si2[r]-si2[l-1]);
tree[son].xx=(r-l+1)*stx*stx+2*stx*(si[r]-si[l-1])+(si2[r]-si2[l-1]);
}
if(tree[now].htag){
tree[son].htag=1;
tree[son].tagx+=tagx;
tree[son].tagy+=tagy;
x=tree[son].x;
y=tree[son].y;
xy=tree[son].xy;
xx=tree[son].xx;
tree[son].x+=(r-l+1)*tagx;
tree[son].y+=(r-l+1)*tagy;
tree[son].xy+=tagx*y+tagy*x+(r-l+1)*tagx*tagy;
tree[son].xx+=2*tagx*x+(r-l+1)*tagx*tagx;
}
}
tree[now].stx=0;tree[now].sty=0;tree[now].hst=0;
tree[now].tagx=0;tree[now].tagy=0;tree[now].htag=0;
}
void BuildTree(int now,int l,int r){
tree[now].l=l;tree[now].r=r;
tree[now].hst=0;
tree[now].htag=0;tree[now].tagx=0;tree[now].tagy=0;
if(l==r){
tree[now].x=inx[l];
tree[now].y=iny[l];
tree[now].xy=inx[l]*iny[l];
tree[now].xx=inx[l]*inx[l];
return;
}
int mid=(l+r)>>1;
BuildTree(lo,l,mid);
BuildTree(ro,mid+1,r);
pushup(now);
}
void Updatasec2(int now,int ll,int rr,double tagx,double tagy){
if(tree[now].l>=ll&&tree[now].r<=rr){
double x,y,xy,xx;
int l=tree[now].l,r=tree[now].r;
x=tree[now].x;y=tree[now].y;xy=tree[now].xy;xx=tree[now].xx;
tree[now].htag=1;tree[now].tagx+=tagx;tree[now].tagy+=tagy;
tree[now].x+=(r-l+1)*tagx;
tree[now].y+=(r-l+1)*tagy;
tree[now].xy+=tagx*y+tagy*x+(r-l+1)*tagx*tagy;
tree[now].xx+=2*tagx*x+(r-l+1)*tagx*tagx;
return;
}
pushdown(now);
int mid=(tree[now].l+tree[now].r)>>1;
if(ll<=mid)Updatasec2(lo,ll,rr,tagx,tagy);
if(rr>mid)Updatasec2(ro,ll,rr,tagx,tagy);
pushup(now);
}
void Updatasec3(int now,int ll,int rr,double stx,double sty){
if(tree[now].l>=ll&&tree[now].r<=rr){
int l=tree[now].l,r=tree[now].r;
tree[now].tagx=0;tree[now].tagy=0;tree[now].htag=0;
tree[now].stx=stx;tree[now].sty=sty;tree[now].hst=1;
tree[now].x=(r-l+1)*stx+(si[r]-si[l-1]);
tree[now].y=(r-l+1)*sty+(si[r]-si[l-1]);
tree[now].xy=(r-l+1)*stx*sty+(stx+sty)*(si[r]-si[l-1])+si2[r]-si2[l-1];
tree[now].xx=(r-l+1)*stx*stx+2*stx*(si[r]-si[l-1])+si2[r]-si2[l-1];
// cout<<"ASD"<<l<<' '<<r<<' '<<tree[now].x<<' '<<tree[now].y<<' '<<tree[now].xy<<' '<<tree[now].xx<<endl;
return;
}
pushdown(now);
int mid=(tree[now].l+tree[now].r)>>1;
if(ll<=mid)Updatasec3(lo,ll,rr,stx,sty);
if(rr>mid)Updatasec3(ro,ll,rr,stx,sty);
pushup(now);
}
double qx,qy,qxy,qxx;
void Querysum(int now,int ll,int rr){
// cout<<now<<endl;
if(tree[now].l>=ll&&tree[now].r<=rr){
qx+=tree[now].x;
qy+=tree[now].y;
qxy+=tree[now].xy;
qxx+=tree[now].xx;
return;
}
pushdown(now);
int mid=(tree[now].l+tree[now].r)>>1;
if(ll<=mid)Querysum(lo,ll,rr);
if(rr>mid)Querysum(ro,ll,rr);
}
int main(){
// freopen("relative.in","r",stdin);
// freopen("relative.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%lf",&inx[i]);
for(int i=1;i<=n;++i)scanf("%lf",&iny[i]);
for(int i=1;i<=n;++i){
si[i]=si[i-1]+i;
si2[i]=si2[i-1]+1.0*i*i;
}
BuildTree(1,1,n);
while(m--){
// cout<<"AD"<<endl;
int opty,l,r;
double a,b;
scanf("%d%d%d",&opty,&l,&r);
if(opty==1){
// printf("now in 1\n");
qx=qy=qxy=qxx=0;
Querysum(1,l,r);
// cout<<qx<<' '<<qy<<' '<<qxy<<' '<<qxx<<endl;
// if(fabs((r-l+1)*qxx-qx*qx)<=1e-9)exit(0);
double ans=(r-l+1)*qxy-qx*qy;
ans=ans/((r-l+1)*qxx-qx*qx);
printf("%.10f\n",ans);
}
if(opty==2){
// printf("now in 2\n");
scanf("%lf%lf",&a,&b);
Updatasec2(1,l,r,a,b);
}
if(opty==3){
// printf("now in 3\n");
scanf("%lf%lf",&a,&b);
Updatasec3(1,l,r,a,b);
}
}
return 0;
}