Luogu P1471 方差
开了十倍空间才过是什么鬼?该不会我线段树炸了吧……
细思极恐
平均数都会求,维护区间和,到时候除一下就好了。
方差的求法如下
(用的Luogu的图片)
因为要维护一个平方,我们可以考虑使用van♂完全平方公式将它拆开,这样只用线段树维护区间和和区间平方和就可以了。
对于区间修改,同样使用完全平方公式。
要注意的一点是,修改时,要先修改平方和,再修改和,因为我们修改平方和时要用到区间和。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1)
using namespace std;
struct zzz{
double sum,pf;
}tree[1000010<<2];
double tag[1000010<<2],a[1000010];
inline void up(int p){
tree[p].sum=tree[ls].sum+tree[rs].sum;
tree[p].pf=tree[ls].pf+tree[rs].pf;
}
void build(int l,int r,int p){
if(l==r){
tree[p].sum=a[l];
tree[p].pf=a[l]*a[l];
return ;
}
build(l,mid,ls); build(mid+1,r,rs);
up(p);
}
inline void down(int l,int r,int p){
//用完全平方公式修改平方和
tree[ls].pf+=2*tree[ls].sum*tag[p]+tag[p]*tag[p]*(mid-l+1);
tree[rs].pf+=2*tree[rs].sum*tag[p]+tag[p]*tag[p]*(r-mid);
//维护区间和
tree[ls].sum+=tag[p]*(mid-l+1);
tree[rs].sum+=tag[p]*(r-mid);
tag[ls]+=tag[p]; tag[rs]+=tag[p]; tag[p]=0;
}
void update(int l,int r,int p,int nl,int nr,double k){
if(l>=nl&&r<=nr){
tree[p].pf+=2*tree[p].sum*k+k*k*(r-l+1);
tree[p].sum+=k*(r-l+1);
tag[p]+=k;
return ;
}
down(l,r,p);
if(nl<=mid) update(l,mid,ls,nl,nr,k);
if(nr>mid) update(mid+1,r,rs,nl,nr,k);
up(p);
}
double query(int l,int r,int p,int nl,int nr){
double ans=0;
down(l,r,p);
if(l>=nl&&r<=nr) return tree[p].sum;
if(nl<=mid) ans+=query(l,mid,ls,nl,nr);
if(nr>mid) ans+=query(mid+1,r,rs,nl,nr);
return ans;
}
double query2(int l,int r,int p,int nl,int nr){
double ans=0;
down(l,r,p);
if(l>=nl&&r<=nr) return tree[p].pf;
if(nl<=mid) ans+=query2(l,mid,ls,nl,nr);
if(nr>mid) ans+=query2(mid+1,r,rs,nl,nr);
return ans;
}
int read(){
int k=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar())
if(c=='-') f=-1;
for(;c>='0'&&c<='9';c=getchar())
k=k*10+c-48;
return k*f;
}
int main(){
int n=read(),m=read();
for(int i=1;i<=n;i++) scanf("%lf",&a[i]);
build(1,n,1);
for(int i=1;i<=m;i++){
int opt=read(),l=read(),r=read();
if(opt==1){
double k; scanf("%lf",&k);
update(1,n,1,l,r,k);
}
if(opt==2){
printf("%.4lf\n",query(1,n,1,l,r)/(r-l+1));
}
if(opt==3){
double sum=query(1,n,1,l,r);
double pj=sum/(r-l+1);
double pf=query2(1,n,1,l,r);
printf("%.4lf\n",(pf-2*sum*pj+pj*pj*(r-l+1))/(r-l+1));
}
}
return 0;
}
Luogu P1471 方差的更多相关文章
- 【题解】Luogu P1471 方差
原题传送门 简单进行推导之后,就能发现很妙的结论 用线段树维护区间和,区间平方和就珂以算出结果 #include <bits/stdc++.h> #define db double #de ...
- Luogu P1471 方差 线段树
那是上上周...也是重构了四遍...后来GG了...今天又拾起,搞了搞终于过了... 好吧就是个线段树,公式懒得推了https://www.cnblogs.com/Jackpei/p/10693561 ...
- 洛谷 P1471 方差
洛谷 P1471 方差 题目背景 滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的 ...
- 【洛谷】【线段树】P1471 方差
[题目背景:] 滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西. [题目描述:] 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差 ...
- 洛谷——P1471 方差
P1471 方差 题目描述 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差. 借一下远航之曲大佬的图片,特别清晰: 那么只要维护区间平方和,就可以 ...
- 【luogu P1471】方差
https://www.luogu.org/problem/show?pid=1471 一眼就能看出是线段树/树状数组题目了. 求平均不用说,线段树/树状数组维护区间和即可. 方差怎么求?先变换下方差 ...
- 洛谷P1471 方差
蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差. ——by 洛谷; http://www.luogu.org/problem/show?pid=1 ...
- P1471 方差
题目 luogu 思路 \[\frac{1}{n}*\sum_{1}^{n}( a_{i}-A)^{2}\] \[\frac{1}{n}*\sum_{1}^{n}( a_{i}^2-2*A*a_{i} ...
- 2018.08.16 洛谷P1471 方差(线段树)
传送门 线段树基本操作. 把那个方差的式子拆开可以发现只用维护一个区间平方和和区间和就可以完成所有操作. 同样区间修改也可以简单的操作. 代码: #include<bits/stdc++.h&g ...
随机推荐
- EL表达式的语法介绍及九大隐含对象
一. 简介 > JSP表达式 <%= %> 用于向页面中输出一个对象. > 到JSP2.0时,在我们的页面中不允许出现 JSP表达式和 脚本片段. > 使用EL表达式来代 ...
- [Inside HotSpot] Epsilon GC
1. Epsilon GC简介 Epsilon GC源于RedHat开发者Aleksey Shipilëv提交的一份JEP 318: Epsilon: A No-Op Garbage Collecto ...
- jquery对象里面的context参数
jquery源码: jQuery = function( selector, context ) { // The jQuery object is actually just the init co ...
- (转)linux自定义开机启动服务和chkconfig使用方法
原文:https://www.cnblogs.com/jimeper/archive/2013/03/12/2955687.html linux自定义开机启动服务和chkconfig使用方法 1. 服 ...
- poi操作word文档文件操作
import org.apache.poi.POITextExtractor; import org.apache.poi.hwpf.extractor.WordExtractor; //得到.doc ...
- 性能测试学习第十一天_Analysis
Analysis的功能:对测试运行结果进行查看,分析和比较 导入分析文件:loadrunner results文件和analysis session文件 Analysis窗口: 1.会话浏览器窗格 2 ...
- Kotlin lateinit 和 by lazy 的区别
1.lazy{} 只能用在val类型, lateinit 只能用在var类型 2.lateinit不能用在可空的属性上和java的基本类型上 3.lateinit可以在任何位置初始化并且可以初始化多次 ...
- 设计模式--观察者模式(KVO)
观察者模式(Observer):观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 举个例子, ...
- 10.&与&&以及位运算符。
这是单独的一块,因为一条讲不清楚(虽然内容也不够一篇),而且我之前也没好好弄清楚,所以有必要写出来. 说位运算符也是从&与&&(|与||类似)之间的区别讲起的.事实上,对于两个 ...
- 阿里云部署安装redis无法访问
ps:我在linux上安装redis后发现一直端口不通连接不上,折腾一晚上.后来在阿里云官方回复(机器人)中看到下面的回复: 2019/02/28 22:50 自己一试,过完是端口监听是本 ...