線分樹、分散、数学(Variance,玲瓏杯Round#5 H lonlife 1063)
分散=(Σ(xi−x)^2)/n,1<=i<=nしか知られていなかった.xは平均数
1本の線分木で分散を維持することはできません.
分散=Var[x]=E[x^2]−E[x]^2は,二乗の期待から所望の二乗を減算することが分かった.
したがって、2つのセグメントツリーで区間と平方の区間とをそれぞれ維持します.そして答えを出せばいい.
私たちは知っています.私たちは知っていますが、私はどうして知りませんか.
これからもっと試合をしなければならないので、試合の収穫が大きいような気がします.
コード#コード#
1本の線分木で分散を維持することはできません.
分散=Var[x]=E[x^2]−E[x]^2は,二乗の期待から所望の二乗を減算することが分かった.
したがって、2つのセグメントツリーで区間と平方の区間とをそれぞれ維持します.そして答えを出せばいい.
私たちは知っています.私たちは知っていますが、私はどうして知りませんか.
これからもっと試合をしなければならないので、試合の収穫が大きいような気がします.
コード#コード#
#include
#define ls (now<<1)
#define rs (ls|1)
using namespace std;
typedef long long ll;
const ll maxn=(1<<16)+10;
typedef pair pdd;
ll n,m;
ll a[maxn];
double tree1[maxn<<2];
double tree2[maxn<<2];
void up_data(ll now)
{
tree1[now]=tree1[ls]+tree1[rs];
tree2[now]=tree2[ls]+tree2[rs];
}
ll K;
void BUILD(ll l,ll r,ll now)
{
if(l==r)
{
tree1[now]=a[K];
tree2[now]=a[K]*a[K];
K++;
return;
}
ll m=(l+r)>>1;
BUILD(l,m,ls);
BUILD(m+1,r,rs);
up_data(now);
}
void A(ll l,ll r,ll now,ll pos,ll val)
{
if(l==r)
{
tree1[now]=val;
tree2[now]=val*val;
return;
}
ll m=(l+r)>>1;
if(pos<=m) A(l,m,ls,pos,val);
else A(m+1,r,rs,pos,val);
up_data(now);
}
pdd Q(ll l,ll r,ll now,ll ql,ll qr)
{
if(ql<=l&&r<=qr) return make_pair(tree1[now],tree2[now]);
ll m=(l+r)>>1;
pdd ansl=make_pair(0,0);
pdd ansr=make_pair(0,0);
if(ql<=m) ansl=Q(l,m,ls,ql,qr);
if(qr>m) ansr=Q(m+1,r,rs,ql,qr);
return make_pair(ansl.first+ansr.first,ansl.second+ansr.second);
}
int main()
{
while(scanf("%lld %lld",&n,&m)==2)
{
for(ll i=1;i<=n;i++)
scanf("%lld",&a[i]);
K=1;
BUILD(1,n,1);
ll x,y;
while(m--)
{
scanf("%lld",&x);
if(x==1)
{
scanf("%lld %lld",&x,&y);
A(1,n,1,x,y);
}
else
{
scanf("%lld %lld",&x,&y);
ll l=y-x+1;
pdd p=Q(1,n,1,x,y);
printf("%lld
",ll(floor((p.second/l-(p.first*p.first/l/l))*l*l+0.5)));
}
}
}
return 0;
}