1 条题解

  • 0
    @ 2025-8-24 21:25:29

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 远航之曲
    **

    搬运于2025-08-24 21:25:28,当前版本为作者最后更新于2016-12-26 20:07:10,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    我们把方差公式展开

    所以只需要维护一个区间平方和和区间和

    当我们更新一个区间加时

    所以pushdown就很好写了

    具体见代码

    想要进一步学习的可以看这里

    #include <cstdio>
    #include <iostream>
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define Maxn 300010
    using namespace std;
    double sega[Maxn],segb[Maxn];
    double mark[Maxn];
    void pushup(int x)
    {
        sega[x]=sega[x<<1]+sega[x<<1|1];
        segb[x]=segb[x<<1]+segb[x<<1|1];
    }
    void pushdown(int rt,int x)
    {
        if (mark[rt])
        {
            segb[rt<<1]+=2*mark[rt]*sega[rt<<1]+(x-x/2)*mark[rt]*mark[rt];
            segb[rt<<1|1]+=2*mark[rt]*sega[rt<<1|1]+(x/2)*mark[rt]*mark[rt];
            sega[rt<<1]+=(x-x/2)*mark[rt];
            sega[rt<<1|1]+=(x/2)*mark[rt];
            mark[rt<<1]+=mark[rt];
            mark[rt<<1|1]+=mark[rt];
            mark[rt]=0;
        }
    }
    void build(int rt,int l,int r)
    {
        if (l==r)
            cin>>sega[rt],segb[rt]=sega[rt]*sega[rt];
        else
        {
            int mid=(l+r)/2;
            build(lson);
            build(rson);
            pushup(rt);
        }
    }
    double query_a(int rt,int l,int r,int L,int R)
    {
        //--L--l--r--R--
        if (l>=L && r<=R)
            return sega[rt];
        else
        {
            pushdown(rt,r-l+1);
            int mid=(r+l)/2;
            double ret=0;
            if (mid>=L)
                ret+=query_a(lson,L,R);
            if (mid<R)
                ret+=query_a(rson,L,R);
            return ret;
        }
    }
    double query_b(int rt,int l,int r,int L,int R)
    {
        //--L--l--r--R--
        if (l>=L && r<=R)
            return segb[rt];
        else
        {
            pushdown(rt,r-l+1);
            int mid=(r+l)/2;
            double ret=0;
            if (mid>=L)
                ret+=query_b(lson,L,R);
            if (mid<R)
                ret+=query_b(rson,L,R);
            return ret;
        }
    }
    void update(int rt,int l,int r,int L,int R,double x)
    {
        if (l>=L && r<=R)
            mark[rt]+=x,segb[rt]+=2*x*sega[rt]+x*x*(r-l+1),sega[rt]+=(r-l+1)*x;
        else
        {
            pushdown(rt,r-l+1);
            int mid=(r+l)/2;
            if (mid>=L)
                update(lson,L,R,x);
            if (mid<R)
                update(rson,L,R,x);
            pushup(rt);
        }
    }
    double sqr(double x)
    {
        return x*x;
    }
    main()
    {
        int n,m,x,y,c;
        double z;
        scanf("%d %d",&n,&m);
        build(1,1,n);
        for (int i=1;i<=m;i++)
        {
            scanf("%d",&c);
            if (c==2)
                scanf("%d%d",&x,&y),printf("%.4lf\n",query_a(1,1,n,x,y)/(y-x+1));
            if (c==1)
                scanf("%d%d",&x,&y),cin>>z,update(1,1,n,x,y,z);
            if (c==3)
            {
                scanf("%d%d",&x,&y);
                double sum1=query_b(1,1,n,x,y)/(y-x+1),sum2=query_a(1,1,n,x,y)/(y-x+1);
                double ans=sum1-sum2*sum2;
                printf("%.4lf\n",ans);
            }
        }
    }
    
    • 1

    信息

    ID
    1854
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者