題目描述
蒟蒻hansbug在一本數學書裡面發現了乙個神奇的數列,包含\(n\)個實數。他想算算這個數列的平均數和方差。
輸入輸出格式
輸入格式
第一行包含兩個正整數\(n\)、\(m\),分別表示數列中實數的個數和操作的個數。
第二行包含\(n\)個實數,其中第\(i\)個實數表示數列的第\(i\)項。
接下來m行,每行為一條操作,格式為以下兩種之一:
操作1:1 x y k ,表示將第\(x\)到第\(y\)項每項加上\(k\),\(k\)為一實數。
操作2:2 x y ,表示求出第\(x\)到第\(y\)項這一子數列的平均數。
操作3:3 x y ,表示求出第\(x\)到第\(y\)項這一子數列的方差。
輸出格式
輸出包含若干行,每行為乙個實數,即依次為每一次操作\(2\)或操作\(3\)所得的結果(所有結果四捨五入保留\(4\)位小數)。
輸入輸出樣例
輸入 #1
5 5
1 5 4 2 3
2 1 4
3 1 5
1 1 1 1
1 2 2 -1
3 1 5
輸出 #13.0000
2.0000
0.8000
題意理解
區間加乙個實數
區間求平均數
區間求方差
演算法解析
首先我們來推倒公式。
先拿出方差公式
\[s^2 = \frac * [(x_1 - \overline)^2 + (x_2 - \overline)^2 + ...+(x_n - \overline)^2 ]
\]根據完全平方公式:
\[(a + b)^2 = a^2 + 2ab + b^2
\]因此帶入引數進去
\[(x_1-\overline)^2=x_1^2+2x\overline+\overline^2
\]接著處理公式
\[s^2 = \frac * (^2 - 2\overline + ^2} + ^2 - 2\overline + ^2} + ... + ^2 - 2\overline + ^2})
\]然後稍微整理一下
\[s^2 = \frac * [(^2 + ^2 + ... + ^2)-2\overline(x_1 + x_2 + ...+x_n) + n\overline^2]
\]然後我們通過平均數公式可得
\[n\overline = x_1 + x_2 + ... + x_n
\]將上面公式,匯入方差公式
\[s^2 = \frac * [(^2 + ^2 + ... + ^2)-2n\overline^2 + n\overline^2]
\]代入後
\[s^2 = \frac * [(^2 + ^2 + ... + ^2)-n\overline^2]
\]因此我們得出了最後的公式
\[s^2 = \frac^2 + ^2 + ... + ^2)} - \overline^2
\]接著我們著重分析分子部分。
\[x_1^2+x_2^2+\dots+x_k^2 \\\\
\]現在所有數增加\(b\),則
\[(x_1+b)^2+(x_2+b)^2+\dots +(x_k+b)^2 \\\\
\]然後定義一下
\[令sum1=x_1+x_2+\dots+x_k \\\\
令sum2=x_1^2+x_2^2+\dots+x_k^2 \\\\
\]由之前的完全平方公式可得:
\[(x_i+b)^2=x_i^2+2 \times x_i \times b+b^2\\\\
\]然後帶入之前的部分
\[(x_1^2+x_2^2+\dots+x_k^2)+2b \times (x_1+x_2+\dots+x_k)+(b^2 \times k) \\\\
\]最後載入定義
\[sum2+2b \times sum1+b^2 \times k \\\\
\]我們終於終於終於將公式打完了。。。。。。
現在我們就可以通過,線段樹來維護本題目了。
維護平方和
維護區間和
請注意,在這裡,我們肯定是要開兩個\(lazy\)標記的;。
但是要記住平方和的懶惰標記,是絕對高於區間和的懶惰標記。
因為,通過公式可得,平方和的修改,是要先使用區間和的。
如果說先修改區間和,那麼平方和的修改必然出現問題。
**解釋
#include using namespace std;
#define lson rt<<1,l,mid
#define rson rt<<1 | 1,mid+1,r
#define mid (l+r>>1)
#define len (r-l+1)
const int n=1e5+20;
int n,m;
struct node
t1[n<<2],t2[n<<2];
double a[n];
inline void push_up(int rt)
void build(int rt,int l,int r)
build(lson);
build(rson);
push_up(rt);
}inline void push_down(int rt,int l,int r)
double query(int rt,int l,int r,int l,int r,int x)
void update(int rt,int l,int r,int l,int r,double v)
push_down(rt,l,r);
if (l<=mid)
update(lson,l,r,v);
if (r>mid)
update(rson,l,r,v);
push_up(rt);
}inline void init()
if (x==2)
printf("%.4lf\n",query(1,1,n,a,b,1)/((b-a+1)*1.0));
if (x==3)
}}signed main()
洛谷 P1471 方差
題目背景 滾粗了的hansbug在收拾舊數學書,然而他發現了什麼奇妙的東西。題目描述 蒟蒻hansbug在一本數學書裡面發現了乙個神奇的數列,包含n個實數。他想算算這個數列的平均數和方差。輸入輸出格式 輸入格式 第一行包含兩個正整數n m,分別表示數列中實數的個數和操作的個數。第二行包含n個實數,其...
洛谷 P1471 方差
蒟蒻hansbug在一本數學書裡面發現了乙個神奇的數列,包含n個實數。他想算算這個數列的平均數和方差。那麼只要維護區間平方和,就可以求方差了。區間平方和,恩,push down稍微改一下即可。注意精度問題。include define n int 1e6 define ll long long us...
洛谷 P1471 方差
區間加,區間查詢,顯然的線段樹 分塊 說實話第一眼看到這個題的時候我是很懵的 線段樹每個區間要維護什麼呢?我們定義 sum sum limits n a i a 1 a 2 ldots a n qquad quad pow sum limits n a i 2 a 1 2 a 2 2 ldots a...