BZOJ 4821 Sdoi2017 相關分析

2021-07-30 22:00:41 字數 3084 閱讀 1081

description

frank對天文學非常感興趣,他經常用望遠鏡看星星,同時記錄下它們的資訊,比如亮度、顏色等等,進而估算出

星星的距離,半徑等等。frank不僅喜歡觀測,還喜歡分析觀測到的資料。他經常分析兩個引數之間(比如亮度和

半徑)是否存在某種關係。現在frank要分析引數x與y之間的關係。他有n組觀測資料,第i組觀測資料記錄了x_i和

y_i。他需要一下幾種操作1 l,r:用直線擬合第l組到底r組觀測資料。用xx表示這些觀測資料中x的平均數,用yy

表示這些觀測資料中y的平均數,即

xx=σx_i/(r-l+1)(l<=i<=r)

yy=σy_i/(r-l+1)(l<=i<=r)

如果直線方程是y=ax+b,那麼a應當這樣計算:

a=(σ(x_i-xx)(y_i-yy))/(σ(x_i-xx)(x_i-xx)) (l<=i<=r)

你需要幫助frank計算a。

2 l,r,s,t:

frank發現測量資料第l組到底r組資料有誤差,對每個i滿足l <= i <= r,x_i需要加上s,y_i需要加上t。

3 l,r,s,t:

frank發現第l組到第r組資料需要修改,對於每個i滿足l <= i <= r,x_i需要修改為(s+i),y_i需要修改為(t+i)。

input

第一行兩個數n,m,表示觀測資料組數和操作次數。

接下來一行n個數,第i個數是x_i。

接下來一行n個數,第i個數是y_i。

接下來m行,表示操作,格式見題目描述。

1<=n,m<=10^5,0<=|s|,|t|,|x_i|,|y_i|<=10^5

保證1操作不會出現分母為0的情況。

output

對於每個1操作,輸出一行,表示直線斜率a。

選手輸出與標準輸出的絕對誤差不超過10^-5即為正確。

sample input

3 51 2 3

1 2 3

1 1 3

2 2 3 -3 2

1 1 2

3 1 2 2 1

1 1 3

sample output

1.0000000000

-1.5000000000

-0.6153846154

hint

source

對於詢問,十分難受,將它化簡。 ∑r

i=l(

xi−x

¯)(y

i−y¯

)∑ri

=l(x

i−x¯

)2

∑ri=

lxi∗

yi−x

¯∑ri

=lyi

−y¯∑

ri=l

xi−(

r−l+

1)∗x

¯∗y¯

∑ri=

lx2i

−2∗x

¯∗∑r

i=lx

i+(r

−l+1

)∗x¯

2 令

len=

r−l+

1 x¯

=∑ri

=lxi

len

y¯=∑

ri=l

yile

n l

en∗∑

ri=l

xi∗y

i−∑r

i=lx

i∗∑r

i=ly

ilen

∗∑ri

=lx2

i−(∑

ri=l

xi)2

可以看出只需要維護∑x

i∗yi

,∑xi

,∑yi

,∑x2

i 做出一棵線段樹,2操作較簡單,3操作可以看作先覆蓋,再進行2操作。

注意標記下傳的時候,先檢查是否有覆蓋標記,如果有將加法標記清除。

更新覆蓋標記時,需要運用數列求和的姿勢,注意要開double,防止溢位。

#include

#include

#define lc num<<1

#define rc num<<1|1

using namespace std

;const int n=100005

;int n,m;

double xx[n],yy[n];

struct segtree

st[4*n];

void update1(int num,double s,double t)

void update2(int num)

void pushup(int num)

void pushdown(int num)

if(st[num].tagx!=0||st[num].tagy!=0)//區間加法

}void build(int num,int l,int r)

int mid=l+r>>1

; build(lc,l,mid),build(rc,mid+1,r);

pushup(num);

}void add(int num,int x,int y,double s,double t)//區間加法

pushdown(num);

if(x

<=st[lc].r)

add(lc,x,y,s,t);

if(y>=st[rc].l)

add(rc,x,y,s,t);

pushup(num);

}void change(int num,int x,int y)//將第i個數改為i

pushdown(num);

if(x

<=st[lc].r)

change(lc,x,y);

if(y>=st[rc].l)

change(rc,x,y);

pushup(num);

}double query(int num,int x,int y,int z)

int main()

else

}return 0

;}

BZOJ4821 SDOI2017 相關分析

bzoj luogu 你需要維護兩個陣列 資瓷一下三種操作。1 給出 l,r 設 overline x,overline y 分別表示區間 l,r 內 x i,y i 的平均數,求 frac r x i overline x y i overline y r x i overline x 2 2 給...

bzoj 4821 Sdoi2017 相關分析

做法顯然 就是維護一顆線段樹 裡面裝4個東西 區間x的和 區間y的和 區間 x 2 的和 區間 xy 的和 然後裝4個標記 add操作對x的影響 add操作對y的影響 cover操作對x的影響 cover操作對y的影響 唯一要想一想的東西在於怎麼維護順序 我一開始的愚蠢做法是每個節點維護乙個nw n...

4821 Sdoi2017 相關分析

4821 sdoi2017 相關分析 time limit 10 sec memory limit 128 mb submit 191 solved 29 submit status discuss description frank對天文學非常感興趣,他經常用望遠鏡看星星,同時記錄下它們的資訊,比...