• 【题解】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;
    }
    
  • 相关阅读:
    Oracle中的to_date参数含义
    Oracle 中 IW和WW 有何差别
    iBaits.Net(1):简介与安装
    带你逛逛诺基亚芬兰总部:满满都是回忆啊
    LINQ的分组聚合技术
    WPF的Docking框架 ——AvalonDock
    iBatis.Net(3):创建SqlMapper实例
    iBatis.Net(2):基本概念与配置
    C#异步编程及其同步机制
    web使用
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10349143.html
Copyright © 2020-2023  润新知