MnZn刚学OI 线段树满江红求调
  • 板块P1471 方差
  • 楼主RP_INT_MAX
  • 当前回复3
  • 已保存回复3
  • 发布时间2022/12/24 16:33
  • 上次更新2023/10/24 06:45:45
查看原帖
MnZn刚学OI 线段树满江红求调
566289
RP_INT_MAX楼主2022/12/24 16:33

rt,小样例过了,第一组大数据出负数

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define L i<<1
#define R i<<1|1
#define for1(i,a,b) for(int i=(a);i<=(b);++i)
#define for2(i,a,b) for(int i=(a);i>=(b);--i)
#define FIO(a) freopen(#a".in","r",stdin);freopen(#a".out","w",stdout);
using namespace std;
typedef double db;
const int N=100010;
db a[N];
struct node{
	int l,r;
	db sum,squ,tag;
}tr[N<<2];
void upd(int i) {tr[i].sum=tr[L].sum+tr[R].sum,tr[i].squ=tr[L].squ+tr[R].squ;}
void build(int i,int l,int r) {
	tr[i].l=l,tr[i].r=r,tr[i].sum=tr[i].squ=tr[i].tag=0;
	if(l==r) return tr[i].sum=a[l],tr[i].squ=a[l]*a[l],void();
	int mid=l+r>>1;
	build(L,l,mid),build(R,mid+1,r),upd(i);
}
void pushdown(int i,int l,int r) {
	if(tr[i].tag) {
		int mid=l+r>>1;
		tr[L].squ+=2*tr[i].tag*tr[L].sum+(mid-l+1)*tr[i].tag*tr[i].tag;
		tr[L].sum+=(mid-l+1)*tr[i].tag,tr[L].tag+=tr[i].tag;
		tr[R].squ+=2*tr[i].tag*tr[R].sum+(r-mid)*tr[i].tag*tr[i].tag;
		tr[R].sum+=(r-mid)*tr[i].tag,tr[R].tag+=tr[i].tag,tr[i].tag=0;
	}
}
void change(int i,int l,int r,db y) {
	if(tr[i].l==l&&tr[i].r==r)
		return tr[i].squ+=2*tr[i].sum*y+y*y*(r-l+1),tr[i].sum+=y*(r-l+1),tr[i].tag+=y,void();
	pushdown(i,l,r);
	int mid=tr[i].l+tr[i].r>>1;
	if(r<=mid) change(L,l,r,y);
	else if(l>mid) change(R,l,r,y);
	else change(L,l,mid,y),change(R,mid+1,r,y);
	upd(i);
}
db get(int i,int l,int r,bool type) {
	if(tr[i].l==l&&tr[i].r==r) return type==1?tr[i].sum:tr[i].squ;
	pushdown(i,l,r);
	int mid=tr[i].l+tr[i].r>>1;
	if(r<=mid) return get(L,l,r,type);
	else if(l>mid) return get(R,l,r,type);
	else return get(L,l,mid,type)+get(R,mid+1,r,type);
}
db k;
int n,m,op,l,r;
signed main () {
//	FIO(P1471_1);
	scanf("%d%d",&n,&m);
	for1(i,1,n) scanf("%lf",a+i);
	build(1,1,n);
	while(m--) {
		scanf("%d%d%d",&op,&l,&r);
		switch(op) {
		case 1:
			scanf("%lf",&k),change(1,l,r,k);
			break;
		case 2:
			printf("%.4lf\n",get(1,l,r,1)/(r-l+1));
			break;
		case 3:
			db tmp=get(1,l,r,1)/(r-l+1);
			printf("%.4lf\n",get(1,l,r,0)/(r-l+1)-tmp*tmp);
		}
	}
	return 0;
}
2022/12/24 16:33
加载中...