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 ...
随机推荐
- jsp页面将日期类型的数据转换成xxxx年xx月xx日xx时xx分
<fmt:formatDate value="${bsjz.cxkssj}" pattern="yyyy"/><span class=&quo ...
- 修改Gradle本地仓库
问题描述 Gradle 默认的本地仓库为 C:\Users\用户名\.gradle,不想让其一直下载东西占用 C 盘资源. 解决方法 新建环境变量名:GRADLE_USER_HOME,变量值为:D:\ ...
- spring容器中的beanName
1. 一个类实现多个接口 如下图中的JobService.java, 此时这个beanName=jobService, 没有包名,类名字首字母小写 可以使用下面三种方式获得这个bean IProce ...
- Floyed-Warshall算法(求任意两点间最短距离)
思路:感觉有点像暴力啊,反正我是觉得很暴力,比如求d[i][j],用这个方法求的话,就直接考虑会不会经过点k(k是任意一点) ,最终求得最小值 看代码 #include<iostream> ...
- kettle5.4ODBC和OCI连接配置
1.kettle 5.4 使用JDBC连接的时候报错(测试不同的数据库,发现只是连接11gRAC 的时候会报JDBC的错误) 具体报错如下 java.sql.SQLException: 建数据库连接出 ...
- jquery checkbox点击选中,再点击取消选中
if(n==1){ if($("#abs1").is(':checked')){ $("#abs1").prop("checked",fal ...
- Hadoop计数器
1. MapReduce计数器是什么 计数器是用来记录Job的执行进度和状态的,其作用类似于日志.我们可以在程序的某个位置插入计数器,记录数据或进度的变化情况. 2. MapReduce计数器能做什么 ...
- SpringBoot | 第七章:过滤器、监听器、拦截器
前言 在实际开发过程中,经常会碰见一些比如系统启动初始化信息.统计在线人数.在线用户数.过滤敏高词汇.访问权限控制(URL级别)等业务需求.这些对于业务来说一般上是无关的,业务方是无需关系的,业务只需 ...
- 排序算法对比,步骤,改进,java代码实现
前言 发现是时候总结一番算法,基本类型的增删改查的性能对比,集合的串并性能的特性,死记太傻了,所以还是写在代码里,NO BB,SHOW ME THE CODE! github地址:https://gi ...
- 认识与入门 MarkDown (转Te_Lee)
Markdown 是一种轻量级的「标记语言」,它的优点很多,目前也被越来越多的写作爱好者,撰稿者广泛使用.看到这里请不要被「标记」.「语言」所迷惑,Markdown 的语法十分简单.常用的标记符号也不 ...