日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jzoj4231-寻找神格【线段树,数学】

發布時間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jzoj4231-寻找神格【线段树,数学】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題


題目大意

4個操作
單點修改,區間修改,區間求和,區間求方差
方差為:∑(xi?ave)2n\frac{\sum(x_i-ave)^2}{n}n(xi??ave)2?
aveaveave為平均值


解題思路

我們將方差的式子分解一下
∑(xi?ave)2n\frac{\sum(x_i-ave)^2}{n}n(xi??ave)2?
∑(xi2?2?x?ave+ave2)n\frac{\sum(x_i^2-2*x*ave+ave^2)}{n}n(xi2??2?x?ave+ave2)?
(∑xi2)?2?(∑xi)?ave+n?ave2n\frac{(\sum x_i^2)-2*(\sum x_i)*ave+n*ave^2}{n}n(xi2?)?2?(xi?)?ave+n?ave2?
然后因為aveaveave可以用區間和求,所以我們只需要多維護一個區間平方和
之后我們考慮如何快速計算,對于一個區間所有數都加上valvalval,之后的平方和
∑(xi+val)2\sum (x_i+val)^2(xi?+val)2
我們將其分解
∑(xi2+2?xi?val+val2)\sum (x_i^2+2*x_i*val+val^2)(xi2?+2?xi??val+val2)
(∑xi2)+(∑xi)?2?val+n?val2(\sum x_i^2)+(\sum x_i)*2*val+n*val^2(xi2?)+(xi?)?2?val+n?val2
然后(∑xi2)(\sum x_i^2)(xi2?)(∑xi)(\sum x_i)(xi?)我們都知道,所以可以直接計算之后的平方和。


codecodecode

#include<cstdio> #define N 100010 #define ll long long #define lodu long double using namespace std; struct tree_node{ll l,r,w,ww,lazy; }t[N<<2]; ll n,q; lodu sum_f; void build(ll k,ll l,ll r)//建樹 {t[k].l=l;t[k].r=r;if(l==r){scanf("%lld",&t[k].w);t[k].ww=t[k].w*t[k].w;return;}ll mid=(l+r)>>1;build(k*2,l,mid);build(k*2+1,mid+1,r);t[k].w=t[k*2].w+t[k*2+1].w;t[k].ww=t[k*2].ww+t[k*2+1].ww; } void get_fan(ll k,ll z)//求區間加了z之后的區間平方和 {t[k].ww=t[k].ww+t[k].w*2*z+z*z*(t[k].r-t[k].l+1);} void downdata(ll k){if(t[k].lazy==0) return;get_fan(k*2,t[k].lazy);get_fan(k*2+1,t[k].lazy); t[k*2].w+=t[k].lazy*(t[k*2].r-t[k*2].l+1);t[k*2+1].w+=t[k].lazy*(t[k*2+1].r-t[k*2+1].l+1);t[k*2].lazy+=t[k].lazy;t[k*2+1].lazy+=t[k].lazy;t[k].lazy=0; }//下傳lazy標記 void change(ll k,ll l,ll r,ll z)//區間修改 {if(t[k].l==l&&t[k].r==r){get_fan(k,z);t[k].lazy+=z;t[k].w+=z*(r-l+1);return;}downdata(k);if(r<=t[k*2].r) change(k*2,l,r,z);else if(l>=t[k*2+1].l) change(k*2+1,l,r,z);else change(k*2,l,t[k*2].r,z),change(k*2+1,t[k*2+1].l,r,z);t[k].ww=t[k*2].ww+t[k*2+1].ww;t[k].w=t[k*2].w+t[k*2+1].w; } ll get_sum(ll k,ll l,ll r)//區間求和和平方和 {if(t[k].l==l&&t[k].r==r){sum_f+=t[k].ww;return t[k].w;}downdata(k);if(r<=t[k*2].r) return get_sum(k*2,l,r);if(l>=t[k*2+1].l) return get_sum(k*2+1,l,r);return get_sum(k*2,l,t[k*2].r)+get_sum(k*2+1,t[k*2+1].l,r); } int main() {//freopen("data.in","r",stdin);//freopen("data.out","w",stdout);scanf("%lld%lld",&n,&q);build(1,1,n);for(ll i=1;i<=q;i++){ll ts,a,b,z;scanf("%lld%lld%lld",&ts,&a,&b);if(ts==0) change(1,a,a,b);else if(ts==1){scanf("%lld",&z);change(1,a,b,z);}else if(ts==2) sum_f=0,printf("%lld\n",get_sum(1,a,b));else{sum_f=0;lodu ave,ans,sum=get_sum(1,a,b),n=b-a+1;ave=sum/n;ans=sum_f+ave*ave*n-sum*ave*2; printf("%0.10Lf\n",ans/n);}} }

總結

以上是生活随笔為你收集整理的jzoj4231-寻找神格【线段树,数学】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。