https://www.luogu.org/problemnew/show/P1471
线段树+展开方差公式+完全平方公式
我们把方差公式展开
所以只需要维护一个区间平方和和区间和
当我们更新一个区间加时
所以pushdown就很好写了
代码:
1 #include<bits/stdc++.h> 2 #define ll int 3 #define db double 4 #define max(x,y) ((x)>(y)?(x):(y)) 5 #define min(x,y) ((x)<(y)?(x):(y)) 6 #define fur(i,x,y) for(i=x;i<=y;i++) 7 #define fdr(i,x,y) for(i=x;i>=y;i--) 8 #define Fur(i,x,y) for(ll i=x;i<=y;i++) 9 #define Fdr(i,x,y) for(ll i=x;i>=y;i--) 10 #define in2(x,y) in(x);in(y) 11 #define in3(x,y,z) in2(x,y);in(z) 12 #define in4(a,b,c,d) in2(a,b);in2(c,d) 13 #define clr(x,y) memset(x,y,sizeof(x)) 14 #define cpy(x,y) memcpy(x,y,sizeof(x)) 15 #define fl(i,x) for(ll i=head[x],to;to=e[i].to,i;i=e[i].next) 16 #define inf 233333333 17 using namespace std; 18 /*---------------------------------------*/ 19 #define pob (fwrite(fob::b,sizeof(char),fob::f-fob::b,stdout),fob::f=fob::b,0) 20 #define pc(x) (*(fob::f++)=(x),(fob::f==fob::g)?pob:0) 21 #define gc ((*fib::f)?(*(fib ::f++)):(fgets(fib::b,sizeof(fib::b),stdin)?(fib::f=fib::b,*(fib::f++)):-1)) 22 namespace fib{char b[300000]= {},*f=b;}inline void in(ll &x){x=0;char c;bool f=0;while((c=gc)>'9'||c<'0')if(c=='-')f=!f;x=c-48;while((c=gc)<='9'&&c>='0')x=x*10+c-48;if(f)x=-x;}namespace fob{char b[300000]= {},*f=b,*g=b+300000-2;}struct foce{~foce(){pob;fflush(stdout);}} _foce;namespace ib{char b[100];}inline void out(ll x){if(x==0){pc(48);return;}if(x<0){pc('-');x=-x;}char *s=ib::b;while(x) *(++s)=x%10,x/=10;while(s!=ib::b) pc((*(s--))+48);}inline void outn(ll x){out(x);pc(' ');} 23 inline void swap(ll &x,ll &y){ll t=x;x=y;y=t;} 24 inline ll jdz(ll x){return x>=0?x:-x;} 25 /*------------------------------------------------------------------------------------------------*/ 26 //上面全是自定义 27 #define N 110000 28 #define idb(x) scanf("%lf",&x) 29 #define Z ll m=(l+r)>>1 30 #define P(x) ((x)*(x)) 31 #define ls rt<<1 32 #define rs rt<<1|1 33 #define pu s[rt]=s[ls]+s[rs];ap[rt]=ap[ls]+ap[rs] 34 //pushup向上更新 35 db a[N],s[N<<2],ap[N<<2],add[N<<2]; 36 //a为原数组,s为区间和,ap为区间中每个数的平方的和,add为懒惰标记 37 ll n,q; 38 inline void pd(ll rt,ll ln,ll rn){ 39 if(add[rt]){ 40 add[ls]+=add[rt];add[rs]+=add[rt]; 41 ap[ls]+=P(add[rt])*ln+2*s[ls]*add[rt]; 42 ap[rs]+=P(add[rt])*rn+2*s[rs]*add[rt]; 43 s[ls]+=add[rt]*ln;s[rs]+=add[rt]*rn; 44 add[rt]=0; 45 } 46 }//pushdown下推 47 inline void build(ll l,ll r,ll rt){ 48 if(l==r){s[rt]=a[l];ap[rt]=P(a[l]);return;} 49 Z;build(l,m,ls);build(m+1,r,rs);pu; 50 } 51 inline void upd(ll L,ll R,db c,ll l,ll r,ll rt){ 52 if(L<=l&&r<=R){ 53 ap[rt]+=(c*c*(r-l+1)+2*s[rt]*c); 54 s[rt]+=((r-l+1)*c); 55 add[rt]+=c; 56 return; 57 } 58 Z;pd(rt,m-l+1,r-m); 59 if(L<=m)upd(L,R,c,l,m,ls); 60 if(R>m)upd(L,R,c,m+1,r,rs); 61 pu; 62 } 63 inline db qs(ll L,ll R,ll l,ll r,ll rt){ 64 if(L<=l&&r<=R)return s[rt]; 65 Z;db ans=0;pd(rt,m-l+1,r-m); 66 if(L<=m)ans+=qs(L,R,l,m,ls); 67 if(R>m)ans+=qs(L,R,m+1,r,rs); 68 return ans; 69 } 70 inline db qp(ll L,ll R,ll l,ll r,ll rt){ 71 if(L<=l&&r<=R)return ap[rt]; 72 Z;db ans=0;pd(rt,m-l+1,r-m); 73 if(L<=m)ans+=qp(L,R,l,m,ls); 74 if(R>m)ans+=qp(L,R,m+1,r,rs); 75 return ans; 76 } 77 int main(){ 78 ll u,x,y,t; 79 db sa,sp,ans,c; 80 cin>>n>>q; 81 Fur(i,1,n)idb(a[i]); 82 build(1,n,1); 83 while(q--){ 84 scanf("%d%d%d",&u,&x,&y); 85 if(u==1){idb(c);upd(x,y,c,1,n,1);continue;} 86 if(u==2)ans=qs(x,y,1,n,1)/(y-x+1); 87 if(u==3){ 88 sa=qs(x,y,1,n,1)/(y-x+1);sp=qp(x,y,1,n,1)/(y-x+1); 89 //sa为平均数,sp为每个数的平方的平均数 90 ans=sp-sa*sa; 91 }//求方差 92 printf("%.4lf ",ans); 93 } 94 }