zoukankan      html  css  js  c++  java
  • 【题解】Luogu P1471 方差

    原题传送门

    简单进行推导之后,就能发现很妙的结论

    用线段树维护区间和,区间平方和就珂以算出结果

    #include <bits/stdc++.h>
    #define db double
    #define N 100005
    using namespace std;
    int n,m; 
    db a[N];
    db sum1[N<<3],sum2[N<<3],tag[N<<3];
    inline void pushup(register int x)
    {
        sum1[x]=sum1[x<<1]+sum1[x<<1|1];
        sum2[x]=sum2[x<<1]+sum2[x<<1|1];
    }
    inline void build(register int x,register int l,register int r)
    {
        if(l==r)
        {
            sum1[x]=a[l],sum2[x]=a[l]*a[l];
            return;
        }
        int mid=l+r>>1;
        build(x<<1,l,mid),build(x<<1|1,mid+1,r);
        pushup(x);
    }
    inline void pushdown(register int x,register int l,register int r)
    {
        int ls=x<<1,rs=x<<1|1,mid=l+r>>1;
        sum2[ls]+=2*tag[x]*sum1[ls]+(mid-l+1)*tag[x]*tag[x];
        sum2[rs]+=2*tag[x]*sum1[rs]+(r-mid)*tag[x]*tag[x];
        sum1[ls]+=tag[x]*(mid-l+1),sum1[rs]+=tag[x]*(r-mid);
        tag[ls]+=tag[x],tag[rs]+=tag[x];
        tag[x]=0;
    }
    inline void update(register int x,register int l,register int r,register int L,register int R,register db v)
    {
        if(L<=l&&r<=R)
        {
            tag[x]+=v,sum2[x]+=2*v*sum1[x]+v*v*(r-l+1),sum1[x]+=v*(r-l+1); 
            return;
        }
        if(tag[x])
            pushdown(x,l,r);
        int mid=l+r>>1;
        if(L<=mid)
            update(x<<1,l,mid,L,R,v);
        if(R>mid)	
            update(x<<1|1,mid+1,r,L,R,v);
        pushup(x);
    }
    inline db query1(register int x,register int l,register int r,register int L,register int R)
    {
        if(L<=l&&r<=R)
            return sum1[x];
        if(tag[x])
            pushdown(x,l,r);
        db res=0;
        int mid=l+r>>1;
        if(L<=mid)
            res+=query1(x<<1,l,mid,L,R);
        if(R>mid)	
            res+=query1(x<<1|1,mid+1,r,L,R);
        return res;
    }
    inline db query2(register int x,register int l,register int r,register int L,register int R)
    {
        if(L<=l&&r<=R)
            return sum2[x];
        if(tag[x])
            pushdown(x,l,r);
        db res=0;
        int mid=l+r>>1;
        if(L<=mid)
            res+=query2(x<<1,l,mid,L,R);
        if(R>mid)	
            res+=query2(x<<1|1,mid+1,r,L,R);
        return res;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(register int i=1;i<=n;++i)
            cin>>a[i];
        build(1,1,n);
        while(m--)
        {
            int opt;
            scanf("%d",&opt);
            if(opt==1)
            {
                int l,r;
                scanf("%d%d",&l,&r);
                db v;
                cin>>v;
                update(1,1,n,l,r,v);
            }
            else if(opt==2)
            {
                int l,r;
                scanf("%d%d",&l,&r);
                db ans=query1(1,1,n,l,r)/(r-l+1);
                printf("%.4lf
    ",ans);
            }
            else
            {
                int l,r;
                scanf("%d%d",&l,&r);
                db a=query2(1,1,n,l,r)/(r-l+1),b=query1(1,1,n,l,r)/(r-l+1);
                db ans=a-b*b;
                printf("%.4lf
    ",ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    hnust Snowman
    hnust 可口可乐大促销
    hnust 聚宝盆
    hnust 搬书
    hnust 神奇的序列
    hnust 懒人多动脑
    hnust CZJ-Superman
    集合Set--BST实现
    快速排序
    位运算符
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10349143.html
Copyright © 2011-2022 走看看