线段树 40pts 求助
  • 板块P1471 方差
  • 楼主zhangzhihao2卷王
  • 当前回复6
  • 已保存回复6
  • 发布时间2023/10/23 21:47
  • 上次更新2023/11/2 11:39:00
查看原帖
线段树 40pts 求助
685325
zhangzhihao2卷王楼主2023/10/23 21:47

AC on #5-8

#include<bits/stdc++.h>
#define int long long
// #define double long double
#define ls 2*x
#define rs 2*x+1
using namespace std;
int n,q;
double sum[500009],tag[500009],fsum[500009],arr[100009];

//向上更新
void pushup(int x){
    sum[x]=sum[ls]+sum[rs];
    fsum[x]=fsum[ls]+fsum[rs];
}

//根据标记更新
void f(int x,int l,int r,double k){
    tag[x]+=k;
    fsum[x]+=2*k*sum[x]+(r-l+1)*k*k;
    sum[x]+=(r-l+1)*k;
}

//标记下传
void pushdown(int x,int l,int r){
    int mid=(l+r)>>1;
    f(ls,l,mid,tag[x]);
    f(rs,mid+1,r,tag[x]);
    tag[x]=0;
}

//建树
void build(int x,int l,int r){
    if(l==r){sum[x]=arr[l],fsum[x]=arr[l]*arr[l];return;}
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(x);
}

//求区间和
double query(int x,int ql,int qr,int l,int r){
    if(ql<=l&&r<=qr) return sum[x];
    int mid=(l+r)>>1;
    double res=0;
    pushdown(x,l,r);
    if(ql<=mid) res+=query(ls,ql,qr,l,mid);
    if(qr>mid) res+=query(rs,ql,qr,mid+1,r);
    return res;
}

//求区间平方和
double fquery(int x,int ql,int qr,int l,int r){
    if(ql<=l&&r<=qr) return fsum[x];
    int mid=(l+r)>>1;
    double res=0;
    pushdown(x,l,r);
    if(ql<=mid) res+=query(ls,ql,qr,l,mid);
    if(qr>mid) res+=query(rs,ql,qr,mid+1,r);
    return res;
}

void update(int x,int ql,int qr,int l,int r,double k){
    if(ql<=l&&r<=qr){
        f(x,l,r,k);
        return;
    }
    int mid=(l+r)>>1;
    pushdown(x,l,r);
    if(ql<=mid) update(ls,ql,qr,l,mid,k);
    if(qr>mid) update(rs,ql,qr,mid+1,r,k);
    pushup(x);
}

int op,xx,yy;
double kk;
signed main(){
    cin>>n>>q;
    for(int i=1;i<=n;i++) scanf("%lf",&arr[i]);
    build(1,1,n);
    for(int i=1;i<=q;i++){
        scanf("%lld%lld%lld",&op,&xx,&yy);
        if(op==1){
            scanf("%lf",&kk);
            update(1,xx,yy,1,n,kk);
        }
        else if(op==2) cout<<fixed<<setprecision(4)<<1.0*query(1,xx,yy,1,n)/(yy-xx+1)<<endl;
        else{
            double fangsum=fquery(1,xx,yy,1,n),nsum=query(1,xx,yy,1,n),xsum=query(1,xx,yy,1,n)/(yy-xx+1);
            cout<<fixed<<setprecision(4)<<(fangsum-2*xsum*nsum+(yy-xx+1)*xsum*xsum)/(yy-xx+1)<<endl;
        }
    }
    return 0;
}
2023/10/23 21:47
加载中...