• Luogu P1471 方差


    题目传送门

    开了十倍空间才过是什么鬼?该不会我线段树炸了吧……
    细思恐极


    平均数都会求,维护区间和,到时候除一下就好了。

    方差的求法如下
    (用的Luogu的图片)
    因为要维护一个平方,我们可以考虑使用van♂完全平方公式将它拆开,这样只用线段树维护区间和和区间平方和就可以了。
    对于区间修改,同样使用完全平方公式。

    要注意的一点是,修改时,要先修改平方和,再修改和,因为我们修改平方和时要用到区间和。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define ls p<<1
    #define rs p<<1|1
    #define mid ((l+r)>>1)
    using namespace std;
    struct zzz{
    	double sum,pf;
    }tree[1000010<<2];
    double tag[1000010<<2],a[1000010];
    inline void up(int p){
    	tree[p].sum=tree[ls].sum+tree[rs].sum;
    	tree[p].pf=tree[ls].pf+tree[rs].pf;
    }
    void build(int l,int r,int p){
    	if(l==r){
    		tree[p].sum=a[l];
    		tree[p].pf=a[l]*a[l];
    		return ;
    	}
    	build(l,mid,ls); build(mid+1,r,rs);
    	up(p);
    }
    inline void down(int l,int r,int p){
    //用完全平方公式修改平方和
    	tree[ls].pf+=2*tree[ls].sum*tag[p]+tag[p]*tag[p]*(mid-l+1);
    	tree[rs].pf+=2*tree[rs].sum*tag[p]+tag[p]*tag[p]*(r-mid);
    //维护区间和
    	tree[ls].sum+=tag[p]*(mid-l+1);
    	tree[rs].sum+=tag[p]*(r-mid);
    	tag[ls]+=tag[p]; tag[rs]+=tag[p]; tag[p]=0;
    }
    void update(int l,int r,int p,int nl,int nr,double k){
    	if(l>=nl&&r<=nr){
    		tree[p].pf+=2*tree[p].sum*k+k*k*(r-l+1);
    		tree[p].sum+=k*(r-l+1);
    		tag[p]+=k;
    		return ;
    	}
    	down(l,r,p);
    	if(nl<=mid) update(l,mid,ls,nl,nr,k);
    	if(nr>mid) update(mid+1,r,rs,nl,nr,k);
    	up(p);
    }
    double query(int l,int r,int p,int nl,int nr){
    	double ans=0;
    	down(l,r,p);
    	if(l>=nl&&r<=nr) return tree[p].sum;
    	if(nl<=mid) ans+=query(l,mid,ls,nl,nr);
    	if(nr>mid) ans+=query(mid+1,r,rs,nl,nr);
    	return ans;
    }
    double query2(int l,int r,int p,int nl,int nr){
    	double ans=0;
    	down(l,r,p);
    	if(l>=nl&&r<=nr) return tree[p].pf;
    	if(nl<=mid) ans+=query2(l,mid,ls,nl,nr);
    	if(nr>mid) ans+=query2(mid+1,r,rs,nl,nr);
    	return ans;
    }
    int read(){
    	int k=0,f=1; char c=getchar();
    	for(;c<'0'||c>'9';c=getchar())
    	  if(c=='-') f=-1;
    	for(;c>='0'&&c<='9';c=getchar())
    	  k=k*10+c-48;
    	return k*f;
    }
    int main(){
    	int n=read(),m=read();
    	for(int i=1;i<=n;i++) scanf("%lf",&a[i]);
    	build(1,n,1);
    	for(int i=1;i<=m;i++){
    		int opt=read(),l=read(),r=read();
    		if(opt==1){
    			double k; scanf("%lf",&k);
    			update(1,n,1,l,r,k);
    		}
    		if(opt==2){
    			printf("%.4lf
    ",query(1,n,1,l,r)/(r-l+1));
    		}
    		if(opt==3){
    			double sum=query(1,n,1,l,r);
    			double pj=sum/(r-l+1);
    			double pf=query2(1,n,1,l,r);
    			printf("%.4lf
    ",(pf-2*sum*pj+pj*pj*(r-l+1))/(r-l+1));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Kubernetes 集成研发笔记
    Rust 1.44.0 发布
    Rust 1.43.0 发布
    PAT 甲级 1108 Finding Average (20分)
    PAT 甲级 1107 Social Clusters (30分)(并查集)
    PAT 甲级 1106 Lowest Price in Supply Chain (25分) (bfs)
    PAT 甲级 1105 Spiral Matrix (25分)(螺旋矩阵,简单模拟)
    PAT 甲级 1104 Sum of Number Segments (20分)(有坑,int *int 可能会溢出)
    java 多线程 26 : 线程池
    OpenCV_Python —— (4)形态学操作
  • 原文地址:https://www.cnblogs.com/morslin/p/11854924.html
Copyright © 2020-2023  润新知