蒟蒻一直 WA 0pts,求大佬解答
  • 板块P1471 方差
  • 楼主makerY
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/7/7 20:08
  • 上次更新2023/11/3 11:08:45
查看原帖
蒟蒻一直 WA 0pts,求大佬解答
642544
makerY楼主2023/7/7 20:08

rtrt

用的方法和大部分(或者全部)题解不一样,我是维护方差的做法。(样例能过)

提交记录

嘤嘤嘤

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N=200010;
struct Node
{
	double sum,sp,tag;//sp是方差
	int pl,pr,len;
}tree[N<<2];
double a[N];
void pushup(Node& p,Node a,Node b)
{
	p.len=a.len+b.len;
	p.sum=a.sum+b.sum;
	const double xp=p.sum/p.len,ap=a.sum/a.len,bp=b.sum/b.len;
	p.sp=(a.len*(a.sp+(ap-xp)*(ap-xp))+b.len*(b.sp+(bp-xp)*(bp-xp)))/p.len;
//	cout<<"sp="<<p.sp<<endl;
}

void addtag(int p,double t)//addtag的时候都是整个区间加一个数,所以方差不会变
{
	tree[p].sum+=t*tree[p].len;
	tree[p].tag+=t;
}
void pushdown(int p)
{
	if(tree[p].tag>0)
	{
		int mid=tree[p].pl+tree[p].pr>>1;
		addtag(p<<1,tree[p].tag);
		addtag(p<<1|1,tree[p].tag);
		tree[p].tag=0;
	}
}
void build(int p,int pl,int pr)
{
	tree[p].pl=pl,tree[p].pr=pr,tree[p].len=pr-pl+1;
	if(pl==pr)
	{
		tree[p].sum=a[pl];
		return;
	}
	int mid=pl+pr>>1;
	build(p<<1,pl,mid);
	build(p<<1|1,mid+1,pr);
	pushup(tree[p],tree[p<<1],tree[p<<1|1]);
}
void update(int p,int pl,int pr,int L,int R,double data)
{
	if(L<=pl&&pr<=R)
	{
		addtag(p,data);
		return;
	}
	pushdown(p);
	int mid=pl+pr>>1;
	if(mid>=L) update(p<<1,pl,mid,L,R,data);
	if(mid<R) update(p<<1|1,mid+1,pr,L,R,data);
	pushup(tree[p],tree[p<<1],tree[p<<1|1]);
}
Node merge(int p,int pl,int pr,int L,int R)
{
	if(L<=pl&&pr<=R) return tree[p];
	pushdown(p);
	int mid=pl+pr>>1;
	double ans=0;
	Node t;
	if(mid>=L&&mid<R) pushup(t,merge(p<<1,pl,mid,L,R),merge(p<<1|1,mid+1,pr,L,R));
	else if(mid>=L) t=merge(p<<1,pl,mid,L,R);
	else if(mid<R) t=merge(p<<1|1,mid+1,pr,L,R);
	return t;
}
int main()
{
	int n,m,x,y,op;
	double k;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lf",&a[i]);
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&op,&x,&y);
		if(op==1) scanf("%lf",&k),update(1,1,n,x,y,k);
		else
		{
			Node t=merge(1,1,n,x,y);
			if(op==2) printf("%.4lf\n",t.sum/t.len);
			if(op==3) printf("%.4lf\n",t.sp);//查询直接用合并区间后的值
		}
	}
	return 0;
}

2023/7/7 20:08
加载中...