學術篇 洛谷1471 方差 分塊做法

2022-09-06 10:51:14 字數 1962 閱讀 1409

寫在前面:大清明節的來上學真是醉了_ (:з」∠) _

題目傳送門:

題目大意:維護乙個數列,支援區間修改,區間查詢平均數,區間查詢方差。

(這種區間修改區間查詢類的一眼看上去就是線段樹嘛……)

我們先把方差公式拆開:

可以看出其實這題我們維護區間和和區間平方和即可……

(更可以堅定地看出線段樹就能維護……)

線段樹?可以。而且應該是標算。

但我就是想用分塊亂搞你咬我啊= =

剛剛去hzwer科普了一下什麼是分塊。。你們也可以去看看分塊入門什麼的。。

發現分塊不失為一種優秀的暴力方式~~

時間複雜度:o(mn^0.5),略慢於線段樹的o(mlogn),但常數小一些,有時還能踩掉線段樹。。

好像比線段樹好寫。。

現在就來處理一些細節問題:

(又要化式子,累死了= =)

完整的塊直接打標記即可(我沿用了線段樹的lazy標記的名字)

不完整的塊,要暴力,同時修改點值和所在塊的sum值(區間和)和sqs值(區間平方和)。。

暴力修改的時候(設修改的值為s):

a[i]+=s; sum[i]+=s; sqs[i]+=2*a[i]*s+sqr(s); //sqr表示平方
查詢區間和,最後除以區間長度(r-l+1)即可。

區間和?

ans+=a[i]+lazy[belong[i]]        //不完整的塊 (i為點)

ans+=sum[i]+block_length*lazy[i] //完整的塊 (i為塊)

由上公式,查詢區間和和區間平方和,最後套公式算即可(區間長度n已知為r-l+1)。

區間平方和?

哦,完整的塊中我們又要化一下式子qaq……

ans+=sqr(a[i]+lazy[belong[i]]) //不完整的塊

ans+=sqs[i]+2*sum[i]*lazy[i]+block_length*sqr(lazy[i])

差不多就是這樣。。化這幾個式子累死我了_ (:з」∠) _

然後剩下的就是亂搞了。。(寫線段樹的也可以像上面講的一樣維護區間。。式子可能稍微不同但精神是相似的!!)

最後的**:

#include 

#include

const

int n=101010;

double a[n],lz[n],sum[n],sqs[n];

int bl[n];

int n,blk,m;

inline

int gnum()

inline

int min(const

int &a,const

int &b)

template

inline t sqr(const t &a)

void add(int l,int r,double s)

double query1(int l,int r)

double query2(int l,int r)

int main()

for(int i=1;i<=m;i++)

if(opt==2)

if(opt==3)}}

唉,記得double和int不要開混了。。

完結撒花o(∩_∩)o

洛谷 1471 方差

竟然用到了數學課本上的知識 真心好題 首先,算術 平均數 a ni 1ai n 方差的兩個最基本的形式 s2 ni 1 a ai 2n ni 1a2i n ni 1 ai 2 n2這道題這麼明顯的區間操作,顯然容易想到線段樹。操作1和2都好說,但是維護方差真的好屎啊 而且還不會 只需要在原來的區間和...

洛谷 1471 方差

題解 1,本題要求維護乙個序列,支援區間加k,詢問區間平均數和方差。3,方差的處理就相對麻煩一些。需要研究一下公式。我們先看看方差的公式 那就是1 n乘上這個式子 也就是區間平方和sqr 區間和sum的兩倍 平均數 e的平方乘區間長len,所得結果再除以區間長len 4,在區間修改的時候,怎麼維護s...

洛谷 P1471 方差

題目背景 滾粗了的hansbug在收拾舊數學書,然而他發現了什麼奇妙的東西。題目描述 蒟蒻hansbug在一本數學書裡面發現了乙個神奇的數列,包含n個實數。他想算算這個數列的平均數和方差。輸入輸出格式 輸入格式 第一行包含兩個正整數n m,分別表示數列中實數的個數和操作的個數。第二行包含n個實數,其...