[SDOI2017]相关分析

传送门

我们要求的 a a a

a = ∑ i = L R ( x i − x ‾ ) ( y i − y ‾ ) ∑ i = L R ( x i − x ‾ ) 2 a=\frac{\sum\limits_{i=L}^R(x_i-\overline x)(y_i-\overline y)}{\sum\limits_{i=L}^R(x_i-\overline x)^2} a=i=LR(xix)2i=LR(xix)(yiy)

展开:

a = ∑ i = L R ( x i y i + x i y ‾ − y i x ‾ − x ‾ y ‾ ) ∑ i = L R ( x i 2 − 2 x i x ‾ + x ‾ 2 ) a=\frac{\sum\limits_{i=L}^R(x_iy_i+x_i\overline y-y_i\overline x-\overline x\overline y)}{\sum\limits_{i=L}^R(x_i^2-2x_i\overline x+\overline x^2)} a=i=LR(xi22xix+x2)i=LR(xiyi+xiyyixxy)

a = ∑ i = L R ( x i y i − x ‾ y ‾ ) + ( R − L + 1 ) × x ‾ × y ‾ − ( R − L + 1 ) × y ‾ × x ‾ ∑ i = L R x i 2 − ( R − L + 1 ) × 2 x ‾ 2 + ( R − L + 1 ) × x ‾ 2 a=\frac{\sum\limits_{i=L}^R(x_iy_i-\overline x\overline y)+(R-L+1)\times\overline x\times\overline y-(R-L+1)\times\overline y\times\overline x}{\sum\limits_{i=L}^Rx_i^2-(R-L+1)\times2\overline x^2+(R-L+1)\times\overline x^2} a=i=LRxi2(RL+1)×2x2+(RL+1)×x2i=LR(xiyixy)+(RL+1)×x×y(RL+1)×y×x

a = ∑ i = L R x i y i − ( R − L + 1 ) × x ‾ y ‾ ∑ i = L R x i 2 − ( R − L + 1 ) × x ‾ 2 a=\frac{\sum\limits_{i=L}^Rx_iy_i-(R-L+1)\times\overline x\overline y}{\sum\limits_{i=L}^Rx_i^2-(R-L+1)\times\overline x^2} a=i=LRxi2(RL+1)×x2i=LRxiyi(RL+1)×xy

所以只要用线段树维护 ∑ x \sum x x ∑ y \sum y y ∑ x 2 \sum x^2 x2 ∑ x y \sum xy xy

2 2 2号操作:

∑ i = L R ( x i + Δ x ) ( y I + Δ y ) \sum\limits_{i=L}^R(x_i+\Delta x)(y_I+\Delta y) i=LR(xi+Δx)(yI+Δy)
= ∑ i = L R ( x i y i + Δ x y i + Δ y x i + Δ x Δ y ) =\sum\limits_{i=L}^R(x_iy_i+\Delta xy_i+\Delta yx_i+\Delta x\Delta y) =i=LR(xiyi+Δxyi+Δyxi+ΔxΔy)
= ∑ i = L R x i y i + ∑ i = L R y i Δ x + ∑ i = L R x i Δ y + ( R − L + 1 ) × Δ x Δ y =\sum\limits_{i=L}^Rx_iy_i+\sum\limits_{i=L}^Ry_i\Delta x+\sum\limits_{i=L}^Rx_i\Delta y+(R-L+1)\times\Delta x\Delta y =i=LRxiyi+i=LRyiΔx+i=LRxiΔy+(RL+1)×ΔxΔy

3 3 3号操作看做是先将元素变为 i i i再执行 2 2 2号操作,记得将原 t a g tag tag清除。

#include<bits/stdc++.h>
#define il inline
#define ls x<<1
#define rs x<<1|1
using namespace std;
const int N=1e5+5;
struct A{double sx,sy,sxy,sxx,tx,ty;int l,r,len,tc;}t[N*4];
double xx[N],yy[N];
il void pushup(int x){t[x].sx=t[ls].sx+t[rs].sx;t[x].sy=t[ls].sy+t[rs].sy;t[x].sxy=t[ls].sxy+t[rs].sxy;t[x].sxx=t[ls].sxx+t[rs].sxx;}
il void build(int x,int l,int r){
	t[x].len=r-l+1;t[x].l=l;t[x].r=r;
	if(l==r){t[x].sx=xx[l];t[x].sy=yy[l];t[x].sxy=xx[l]*yy[l];t[x].sxx=xx[l]*xx[l];return;}
	int mid=l+r>>1;build(ls,l,mid);build(rs,mid+1,r);pushup(x);
}il double calc(int x){return 1.0*x*(x+1)*(2*x+1)/6.0;}
il void update1(int x,double dx,double dy){
	t[x].sxy+=t[x].sx*dy+t[x].sy*dx+t[x].len*dx*dy;t[x].sxx+=t[x].sx*dx*2+t[x].len*dx*dx;
	t[x].sx+=t[x].len*dx;t[x].sy+=t[x].len*dy;t[x].tx+=dx;t[x].ty+=dy;	
}il void update2(int x){
	t[x].sx=t[x].sy=1.0*(t[x].l+t[x].r)*t[x].len/2.0;
	t[x].sxy=t[x].sxx=calc(t[x].r)-calc(t[x].l-1);
	t[x].tc=1;t[x].tx=t[x].ty=0;
}il void pushdown(int x){
	if(t[x].tc){update2(ls);update2(rs);t[x].tc=0;}
	if(t[x].tx||t[x].ty){update1(ls,t[x].tx,t[x].ty);update1(rs,t[x].tx,t[x].ty);t[x].tx=t[x].ty=0;}
}il void add(int x,int L,int R,int dx,int dy){
	if(L<=t[x].l&&t[x].r<=R) return (void)(update1(x,dx,dy));
	pushdown(x);int mid=t[x].l+t[x].r>>1;
	if(L<=mid) add(ls,L,R,dx,dy);if(mid<R) add(rs,L,R,dx,dy);
	pushup(x);
}il void change(int x,int L,int R){
	if(L<=t[x].l&&t[x].r<=R) return (void)(update2(x));
	pushdown(x);int mid=t[x].l+t[x].r>>1;
	if(L<=mid) change(ls,L,R);if(mid<R) change(rs,L,R);
	pushup(x);
}il double qry(int x,int L,int R,int o){
	if(L<=t[x].l&&t[x].r<=R){if(o==1) return t[x].sx;if(o==2) return t[x].sy;if(o==3) return t[x].sxy;if(o==4) return t[x].sxx;}
	pushdown(x);int mid=t[x].l+t[x].r>>1;double res=0;
	if(L<=mid) res+=qry(ls,L,R,o);if(mid<R) res+=qry(rs,L,R,o);
	return res;
}int main(){
	int n,m,o,l,r,dx,dy;scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) scanf("%lf",&xx[i]);
	for(int i=1;i<=n;++i) scanf("%lf",&yy[i]);
	build(1,1,n);
	while(m--){
		scanf("%d%d%d",&o,&l,&r);
		if(o==1){
			double res1=qry(1,l,r,1),res2=qry(1,l,r,2),res3=qry(1,l,r,3),res4=qry(1,l,r,4);
			double p=res3-res1*res2/(r-l+1),q=res4-res1*res1/(r-l+1);
			printf("%.10lf\n",p/q);
		}else{scanf("%d%d",&dx,&dy);if(o==3) change(1,l,r);add(1,l,r,dx,dy);}
	}return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值