BZOJ 4821 [Sdoi2017]相关分析

题解:线段树

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;
}

  

posted @ 2018-03-02 15:06  ws_zzy  阅读(125)  评论(0编辑  收藏  举报