• 方差


    链接:https://www.luogu.org/problemnew/show/P1471

    题解:

    对式子进行一些化简就会发现等价于在求方差

    裸的线段树

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 111111
    #define mid (p[x].h+p[x].t)/2
    int n,m;
    double a[maxn],b[maxn];
    struct re
    {
        int h,t;
        double x1,x2,lazy;
    }p[maxn*4];
    void updata(int x)
    {
        p[x].x1=p[x*2].x1+p[x*2+1].x1;
        p[x].x2=p[x*2].x2+p[x*2+1].x2;
    }
    void build(int x,int h,int t)
    {
        p[x].h=h; p[x].t=t;
        if (h==t)
        {
            p[x].x1=a[h]; p[x].x2=b[h];
            return;
        }
        build(x*2,h,mid); build(x*2+1,mid+1,t);
        updata(x);
    }
    void down(int x)
    {
        if (p[x].lazy)
        { 
            p[x].x2+=2*p[x].x1*p[x].lazy+(p[x].t-p[x].h+1)*p[x].lazy*p[x].lazy;
            p[x].x1+=(p[x].t-p[x].h+1)*p[x].lazy;
            if (p[x].h!=p[x].t)
            {
              p[x*2].lazy+=p[x].lazy;
              p[x*2+1].lazy+=p[x].lazy;    
            } 
            p[x].lazy=0;
        }
    }
    void change(int x,int h,int t,double sum)
    {
        down(x);
        if (p[x].h>t||p[x].t<h) return;
        if (h<=p[x].h&&p[x].t<=t)
        {
            p[x].lazy+=sum; down(x);
            return;
        }
        change(x*2,h,t,sum); change(x*2+1,h,t,sum);
        updata(x);
    }
    double query1(int x,int h,int t)
    {
        down(x);
        if (p[x].h>t||p[x].t<h) return(0);
        if (h<=p[x].h&&p[x].t<=t)
        {
            return(p[x].x1);
        } 
        return(query1(x*2,h,t)+query1(x*2+1,h,t));
    }
    double query2(int x,int h,int t)
    {
        down(x);
        if (p[x].h>t||p[x].t<h) return(0);
        if (h<=p[x].h&&p[x].t<=t)
        {
            return(p[x].x2);
        } 
        return(query2(x*2,h,t)+query2(x*2+1,h,t));
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        cin>>n>>m;
        for (int i=1;i<=n;i++)
        {  
          cin>>a[i]; b[i]=(a[i]*a[i]);
        }
        build(1,1,n);
        for (int i=1;i<=m;i++)
        {
            int c,d,e; double f;
            cin>>c;
            if (c==1)
            {
                cin>>d>>e>>f;
                change(1,d,e,f);
            }
            if (c==2)
            {
                cin>>d>>e;
                printf("%.4f
    ",query1(1,d,e)/(e-d+1));
            }
            if (c==3)
            {
                cin>>d>>e;
                double x=query1(1,d,e),y=x/(e-d+1);
                printf("%.4f
    ",(query2(1,d,e)-2*y*x)/(e-d+1)+y*y);
            }
        }
    }
  • 相关阅读:
    转载 消灭程序员需要百年吗?(重要参考)
    转载的一篇,代码规范
    自改的删除数据库中所有外键语句
    [转]批量禁用外键后,清空表数据
    我的分组分页查询语句
    Yii 分页方法总结
    25个Apache性能优化技巧推荐
    浅谈MindSpore的动态Shape
    C++开发总结 A
    Linux环境下开发常用命令汇总 A
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8401504.html
Copyright © 2020-2023  润新知