zoukankan      html  css  js  c++  java
  • [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
    ",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
    
  • 相关阅读:
    C++ ORM ODB 入门(三)
    C++ ORM ODB 入门介绍(二)
    最简便的MySql数据库备份方法
    快速高效的破解MySQL本地和远程密码
    C++ ORM ODB 入门介绍(一)
    NeHe OpenGL教程 第三十九课:物理模拟
    NeHe OpenGL教程 第三十八课:资源文件
    NeHe OpenGL教程 第三十七课:卡通映射
    NeHe OpenGL教程 第三十六课:从渲染到纹理
    NeHe OpenGL教程 第三十五课:播放AVI
  • 原文地址:https://www.cnblogs.com/mleautomaton/p/11423039.html
Copyright © 2011-2022 走看看