4821: [sdoi2017]相關分析
time limit: 10 sec memory limit: 128 mb
submit: 191 solved: 29
[submit][status][discuss]
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
請不要提交,尚無spj
source
鳴謝infinityedge上傳
[submit][status][discuss]
要了下資料發現極限資料的確挺極限的。。。貌似是要用另外乙個公式來維護不然就溢位了。。。 a^
=∑ri
=l(x
i−x¯
)(yi
−y¯)
∑ri=
l(xi
−x¯)
2=(∑
ri=l
xiyi
)−nx
¯y¯(
∑ri=
lx2i
)−nx
¯2於是我們只要維護區間內x,
y,xy
的和就行了
推推公式大力線段樹一波就好
沒有spj…
儲存要用long double,不然溢位了…
中間計算還是要用long double,不然還是溢位…
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define max(a,b) ((a) > (b) ? (a) : (b))
using
namespace
std;
typedef
long
double db;
typedef
long
long ll;
const
int t = 4;
const ll inf = 1e16;
const
int maxn = 1e5 + 10;
int n,m;
ll a[maxn],b[maxn],s0[maxn],s1[maxn];
db sx[maxn*t],sy[maxn*t],sxy[maxn*t],sm[maxn*t],ax[maxn*t],cx[maxn*t],ay[maxn*t],cy[maxn*t];
db sx,sy,sxy,sm,x,y;
inline
void maintain(int o)
inline
void build(int o,int l,int r)
int mid = l + r >> 1;
build(o<<1,l,mid); build(o<<1|1,mid+1,r);
maintain(o);
}inline
void push_add(int o,ll ax,ll ay)
inline
void push_cov(int o,ll cx,ll cy)
inline
void pushdown(int o,int l,int r)
else
ax[o] = cx[o] = inf;
}inline
void query(int o,int l,int r,int ql,int qr)
int mid = l + r >> 1;
if (ql <= mid) query(o<<1,l,mid,ql,qr);
if (qr > mid) query(o<<1|1,mid+1,r,ql,qr);
}inline
void modify(int o,int l,int r,int ql,int qr,ll ax,ll ay)
int mid = l + r >> 1; pushdown(o,l,r);
if (ql <= mid) modify(o<<1,l,mid,ql,qr,ax,ay); else pushdown(o<<1,l,mid);
if (qr > mid) modify(o<<1|1,mid+1,r,ql,qr,ax,ay); else pushdown(o<<1|1,mid+1,r);
maintain(o);
}inline
void cover(int o,int l,int r,int ql,int qr,ll cx,ll cy)
int mid = l + r >> 1; pushdown(o,l,r);
if (ql <= mid && mid < qr)
else
maintain(o);
}inline
int getint()
while ('0'
<= ch && ch <= '9')
ret = ret * 10 + ch - '0',ch = getchar();
return ret * a;
}int main()
build(1,1,n);
while (m--)
else
if (typ == 2)
else
if (typ == 3)
}return
0;}
BZOJ 4821 Sdoi2017 相關分析
description frank對天文學非常感興趣,他經常用望遠鏡看星星,同時記錄下它們的資訊,比如亮度 顏色等等,進而估算出 星星的距離,半徑等等。frank不僅喜歡觀測,還喜歡分析觀測到的資料。他經常分析兩個引數之間 比如亮度和 半徑 是否存在某種關係。現在frank要分析引數x與y之間的關係...
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...