[SDOI2017]相关分析

把求\(a\)的式子拆开,然后把所有的需要求的东西用线段树维护即可。

// luogu-judger-enable-o2
/*
  mail: mleautomaton@foxmail.com
  author: MLEAutoMaton
  This Code is made by MLEAutoMaton
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi(){
	int f=1,sum=0;char ch=getchar();
	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
	return f*sum;
}
const int N=100010;
typedef pair<double,double> pii;
#define mp make_pair
struct node{
	double xymul,sumx,sumy,xsqr;
	int l,r;
	pii tag1,tag2;
	bool flag1,flag2;
}t[N<<2];
int n,m,x[N],y[N];
double sum[N],sumsqr[N];
pii operator+(pii a,pii b){return mp(a.first+b.first,a.second+b.second);}
double sumid(int l,int r){return sum[r]-sum[l-1];}
double sumidsqr(int l,int r){return sumsqr[r]-sumsqr[l-1];}
void pushup(int o){
	t[o].sumx=t[o<<1].sumx+t[o<<1|1].sumx;
	t[o].sumy=t[o<<1].sumy+t[o<<1|1].sumy;
	t[o].xsqr=t[o<<1].xsqr+t[o<<1|1].xsqr;
	t[o].xymul=t[o<<1].xymul+t[o<<1|1].xymul;
}
void puttag1(int o,double S,double T){
	int l=t[o].l,r=t[o].r;t[o].flag1=1;
	t[o].tag1.first+=S;t[o].tag1.second+=T;
	t[o].xsqr+=2*t[o].sumx*S+S*S*(r-l+1);
	t[o].xymul+=S*T*(r-l+1)+t[o].sumy*S+t[o].sumx*T;
	t[o].sumx+=(r-l+1)*S;t[o].sumy+=(r-l+1)*T;
}
void puttag2(int o,double S,double T){
	int l=t[o].l,r=t[o].r;
	t[o].tag2=mp(S,T);t[o].flag2=1;t[o].tag1=mp(0,0);
	t[o].xsqr=(r-l+1)*S*S+sumidsqr(l,r)+2*S*sumid(l,r);
	t[o].xymul=S*T*(r-l+1)+sumid(l,r)*(S+T)+sumidsqr(l,r);
	t[o].sumx=S*(r-l+1)+sumid(l,r);t[o].sumy=T*(r-l+1)+sumid(l,r);
}
void pushdown(int o){
	if(t[o].flag2){
		puttag2(o<<1,t[o].tag2.first,t[o].tag2.second);
		puttag2(o<<1|1,t[o].tag2.first,t[o].tag2.second);
		t[o].flag2=0;t[o].tag2=mp(0,0);
	}
	if(t[o].flag1){
		puttag1(o<<1,t[o].tag1.first,t[o].tag1.second);
		puttag1(o<<1|1,t[o].tag1.first,t[o].tag1.second);
		t[o].flag1=0;t[o].tag1=mp(0,0);
	}
}
void build(int o,int l,int r){
	t[o].l=l;t[o].r=r;t[o].tag1=mp(0,0);t[o].tag2=mp(0,0);
	t[o].flag1=false;t[o].flag2=false;
	if(l==r){
		t[o].sumx=x[l];t[o].sumy=y[l];
		t[o].xymul=1ll*x[l]*y[l];t[o].xsqr=1ll*x[l]*x[l];
		return;
	}
	int mid=(l+r)>>1;
	build(o<<1,l,mid);build(o<<1|1,mid+1,r);
	pushup(o);
}
//	int xymul,sumx,sumy,xsqr;
double query_sumx(int o,int l,int r,int posl,int posr){
	if(posl<=l && r<=posr)return t[o].sumx;
	int mid=(l+r)>>1;double ret=0;pushdown(o);
	if(posl<=mid)ret+=query_sumx(o<<1,l,mid,posl,posr);
	if(mid<posr)ret+=query_sumx(o<<1|1,mid+1,r,posl,posr);
	return ret;
}
double query_sumy(int o,int l,int r,int posl,int posr){
	if(posl<=l && r<=posr)return t[o].sumy;
	int mid=(l+r)>>1;double ret=0;pushdown(o);
	if(posl<=mid)ret+=query_sumy(o<<1,l,mid,posl,posr);
	if(mid<posr)ret+=query_sumy(o<<1|1,mid+1,r,posl,posr);
	return ret;
}
double query_xsqr(int o,int l,int r,int posl,int posr){
	if(posl<=l && r<=posr)return t[o].xsqr;
	int mid=(l+r)>>1;double ret=0;pushdown(o);
	if(posl<=mid)ret+=query_xsqr(o<<1,l,mid,posl,posr);
	if(mid<posr)ret+=query_xsqr(o<<1|1,mid+1,r,posl,posr);
	return ret;
}
double query_xymul(int o,int l,int r,int posl,int posr){
	if(posl<=l && r<=posr)return t[o].xymul;
	int mid=(l+r)>>1;double ret=0;pushdown(o);
	if(posl<=mid)ret+=query_xymul(o<<1,l,mid,posl,posr);
	if(mid<posr)ret+=query_xymul(o<<1|1,mid+1,r,posl,posr);
	return ret;
}
void modify_sum(int o,int l,int r,int posl,int posr,double S,double T){
	if(posl<=l && r<=posr){puttag1(o,S,T);return;}
	int mid=(l+r)>>1;pushdown(o);
	if(posl<=mid)modify_sum(o<<1,l,mid,posl,posr,S,T);
	if(mid<posr)modify_sum(o<<1|1,mid+1,r,posl,posr,S,T);
	pushup(o);
}
void modify_ins(int o,int l,int r,int posl,int posr,double S,double T){
	if(posl<=l && r<=posr){puttag2(o,S,T);return;}
	int mid=(l+r)>>1;pushdown(o);
	if(posl<=mid)modify_ins(o<<1,l,mid,posl,posr,S,T);
	if(mid<posr)modify_ins(o<<1|1,mid+1,r,posl,posr,S,T);
	pushup(o);
}
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
#endif
	n=gi();m=gi();
	for(int i=1;i<=n;i++)sum[i]=sum[i-1]+i;
	for(int i=1;i<=n;i++)sumsqr[i]=sumsqr[i-1]+1ll*i*i;
	for(int i=1;i<=n;i++)x[i]=gi();
	for(int i=1;i<=n;i++)y[i]=gi();
	build(1,1,n);
	while(m--){
		int opt=gi(),L=gi(),R=gi();
		if(opt==1){
			int len=R-L+1;
			double sumx=query_sumx(1,1,n,L,R),sumy=query_sumy(1,1,n,L,R),xymul=query_xymul(1,1,n,L,R);
			double xba=sumx*1./len,yba=sumy*1./len;
			double up=xymul-yba*sumx-xba*sumy+len*xba*yba;
		    double xsqr=query_xsqr(1,1,n,L,R);
			double down=xsqr+len*xba*xba-2*xba*sumx;
			printf("%.10lf\n",up/down);
		}
		else{
			int S=gi(),T=gi();
			if(opt==2)modify_sum(1,1,n,L,R,S,T);
			if(opt==3)modify_ins(1,1,n,L,R,S,T);
		}
	}
	return 0;
}
#undef mp
posted @ 2019-08-28 11:31  QwQGJH  阅读(142)  评论(0编辑  收藏  举报