Luogu P1471 variance

Topic Portal

Opened a tenfold space after just what the hell? The tree line I will not fry it ......
fine very think fear


The average will seek, maintenance intervals and, in addition to the time just fine.

Seeking variance as follows
(with Luogu picture)
because you want to maintain a square, we can consider the use ofvan♂Completely square formula will it apart, so that only the tree line and the maintenance interval and the interval of squares on it.
For the range of changes, using the same formula perfect square.

One point to note is that when you modify, amend first square and then modify and, because we have modified the square and when to use and range.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1)
using namespace std;
struct zzz{
    double sum,pf;
}tree[1000010<<2];
double tag[1000010<<2],a[1000010];
inline void up(int p){
    tree[p].sum=tree[ls].sum+tree[rs].sum;
    tree[p].pf=tree[ls].pf+tree[rs].pf;
}
void build(int l,int r,int p){
    if(l==r){
        tree[p].sum=a[l];
        tree[p].pf=a[l]*a[l];
        return ;
    }
    build(l,mid,ls); build(mid+1,r,rs);
    up(p);
}
inline void down(int l,int r,int p){
//用完全平方公式修改平方和
    tree[ls].pf+=2*tree[ls].sum*tag[p]+tag[p]*tag[p]*(mid-l+1);
    tree[rs].pf+=2*tree[rs].sum*tag[p]+tag[p]*tag[p]*(r-mid);
//维护区间和
    tree[ls].sum+=tag[p]*(mid-l+1);
    tree[rs].sum+=tag[p]*(r-mid);
    tag[ls]+=tag[p]; tag[rs]+=tag[p]; tag[p]=0;
}
void update(int l,int r,int p,int nl,int nr,double k){
    if(l>=nl&&r<=nr){
        tree[p].pf+=2*tree[p].sum*k+k*k*(r-l+1);
        tree[p].sum+=k*(r-l+1);
        tag[p]+=k;
        return ;
    }
    down(l,r,p);
    if(nl<=mid) update(l,mid,ls,nl,nr,k);
    if(nr>mid) update(mid+1,r,rs,nl,nr,k);
    up(p);
}
double query(int l,int r,int p,int nl,int nr){
    double ans=0;
    down(l,r,p);
    if(l>=nl&&r<=nr) return tree[p].sum;
    if(nl<=mid) ans+=query(l,mid,ls,nl,nr);
    if(nr>mid) ans+=query(mid+1,r,rs,nl,nr);
    return ans;
}
double query2(int l,int r,int p,int nl,int nr){
    double ans=0;
    down(l,r,p);
    if(l>=nl&&r<=nr) return tree[p].pf;
    if(nl<=mid) ans+=query2(l,mid,ls,nl,nr);
    if(nr>mid) ans+=query2(mid+1,r,rs,nl,nr);
    return ans;
}
int read(){
    int k=0,f=1; char c=getchar();
    for(;c<'0'||c>'9';c=getchar())
      if(c=='-') f=-1;
    for(;c>='0'&&c<='9';c=getchar())
      k=k*10+c-48;
    return k*f;
}
int main(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++) scanf("%lf",&a[i]);
    build(1,n,1);
    for(int i=1;i<=m;i++){
        int opt=read(),l=read(),r=read();
        if(opt==1){
            double k; scanf("%lf",&k);
            update(1,n,1,l,r,k);
        }
        if(opt==2){
            printf("%.4lf\n",query(1,n,1,l,r)/(r-l+1));
        }
        if(opt==3){
            double sum=query(1,n,1,l,r);
            double pj=sum/(r-l+1);
            double pf=query2(1,n,1,l,r);
            printf("%.4lf\n",(pf-2*sum*pj+pj*pj*(r-l+1))/(r-l+1));
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/morslin/p/11854924.html