【洛谷】【线段树】P1471 方差
【题目背景:】
滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西。
【题目描述:】
蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数。他想算算这个数列的平均数和方差。
【输入格式:】
第一行包含两个正整数N、M,分别表示数列中实数的个数和操作的个数。
第二行包含N个实数,其中第i个实数表示数列的第i项。
接下来M行,每行为一条操作,格式为以下两种之一:
操作1:1 x y k ,表示将第x到第y项每项加上k,k为一实数。
操作2:2 x y ,表示求出第x到第y项这一子数列的平均数。
操作3:3 x y ,表示求出第x到第y项这一子数列的方差。
【输出格式:】
输出包含若干行,每行为一个实数,即依次为每一次操作2或操作3所得的结果(所有结果四舍五入保留4位小数)。
输入样例#: - 输出样例#:
3.0000
2.0000
0.8000
输入输出样例
【算法分析:】
支持区间修改,区间询问,常规做法线段树
关于平均值;
维护一个区间和,区间平均值就是区间和/区间长度
关于方差:
设ave为序列a的平均值
s2 = [(a1 - ave)2 + (a2 - ave)2 + ... + (an - ave)2] / n
展开可得:s2 = a12 + a22 + ... + an2 - 2 * ave(a1 + a2 + ... + an) + n * ave2
可以发现,只需要多维护一个区间平方和,就可以求出方差。
但如果要修改某一区间内元素的值呢?
(a1 + v)2 + (a2 + v)2 + ... + (an + v)2
= a12 + a22 + ... + an2 + 2v(a1 + a2 + .. + an) + n * v2
维护区间平方和时,标记下传和修改被包含区间值的操作是一样的,答案就很显然了.
注意坑点:读入的序列是实型,方差平均值和要修改的值也是实型,修改时传参的修改值也要是实型.
【代码:】
//P1471 方差
#include<iostream>
#include<cstdio>
using namespace std; const int MAXN = 1e5 + ; int n, m;
double a[MAXN];
struct Segment {
double sum, squ, lazy;
}t[MAXN << ]; void Build(int o, int l, int r) {
if(l == r) {
t[o].sum = a[l];
t[o].squ = a[l] * a[l];
}
else {
int mid = (l + r) >> ;
Build(o << , l, mid);
Build(o << |, mid + , r);
t[o].sum = t[o << ].sum + t[o << |].sum;
t[o].squ = t[o << ].squ + t[o << |].squ;
}
}
inline void down(int o, int len) {
if(!t[o].lazy) return;
t[o << ].squ += * t[o].lazy * t[o << ].sum
+ t[o].lazy * t[o].lazy * (len - (len >> ));
t[o << |].squ += * t[o].lazy * t[o << |].sum
+ t[o].lazy * t[o].lazy * (len >> );
t[o << ].sum += t[o].lazy * (len - (len >> ));
t[o << |].sum += t[o].lazy * (len >> );
t[o << ].lazy += t[o].lazy;
t[o << |].lazy += t[o].lazy;
t[o].lazy = ;
}
void Update(int o, int l, int r, int ul, int ur, double v) {
if(ul <= l && r <= ur) {
t[o].squ += * v * t[o].sum + v * v * (r - l + );
t[o].sum += v * (r - l + );
t[o].lazy += v;
}
else {
down(o, r - l + );
int mid = (l + r) >> ;
if(ul <= mid) Update(o << , l, mid, ul, ur, v);
if(ur > mid) Update(o << |, mid + , r, ul, ur, v);
t[o].sum = t[o << ].sum + t[o << |].sum;
t[o].squ = t[o << ].squ + t[o << |].squ;
}
} double ssum, ssqu;
void Query(int o, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) {
ssum += t[o].sum;
ssqu += t[o].squ;
}
else {
down(o, r - l + );
int mid = (l + r) >> ;
if(ql <= mid) Query(o << , l, mid, ql, qr);
if(qr > mid) Query(o << |, mid + , r, ql, qr);
}
} inline double Average(int l, int r) {
ssum = ssqu = ;
Query(, , n, l, r);
return ssum * 1.0 / (r - l + );
}
inline double S2(int l, int r) {
ssum = ssqu = ;
int num = r - l + ;
Query(, , n, l, r);
double ave = ssum * 1.0 / num;
double ret = ssqu - * ave * ssum + num * ave * ave;
return ret / num;
} int main() {
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i)
scanf("%lf", &a[i]);
Build(, , n);
while(m--) {
int fl, x, y;
scanf("%d%d%d", &fl, &x, &y);
if(fl == ) printf("%.4lf\n", Average(x, y));
else if(fl == ) printf("%.4lf\n", S2(x, y));
else {
double k;
scanf("%lf", &k);
Update(, , n, x, y, k);
}
}
}
【洛谷】【线段树】P1471 方差的更多相关文章
- 【算法学习】【洛谷】树链剖分 & P3384 【模板】树链剖分 P2146 软件包管理器
刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...
- 洛谷P3384 树链剖分
如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式: 2 x ...
- 洛谷P3248 树 [HNOI2016] 主席树+倍增+分治
正解:主席树+倍增+分治 解题报告: 传送门! 首先看到这题会想到之前考过的这题 但是那题其实简单一些,,,因为那题只要用个分治+预处理就好,只是有点儿思维难度而已 这题就不一样,因为它说了是按照原树 ...
- 洛谷P3368 树状数组2 树状数组+差分
正解:树状数组+差分 解题报告: 戳我! 不得不说灵巧真滴是越来越弱了...连模板题都要放上来了QAQ 因为今天考试的T3正解要用到树状数组这才惊觉树状数组掌握得太太太太差了...之前一直靠线段树续着 ...
- 洛谷P2146 树链剖分
题意 思路:直接树链剖分,用线段树维护即可,算是树剖的经典题目吧. 代码: #include <bits/stdc++.h> #define ls(x) (x << 1) #d ...
- 洛谷P3374树状数组1
下有彩蛋(from https://www.cnblogs.com/wuwangchuxin0924/p/5921130.html)树状数组的blog写的最好的是这位//https://www.cnb ...
- 洛谷 P3384树链剖分 题解
题面 挺好的一道树剖模板: 首先要学会最模板的树剖: 然后这道题要注意几个细节: 初始化时,seg[0]=1,seg[root]=1,top[root]=root,rev[1]=root; 在线段树上 ...
- 洛谷 P3384 树链剖分(模板题)
题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...
- 洛谷P1268 树的重量
P1268 树的重量 85通过 141提交 题目提供者该用户不存在 标签树形结构 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 有这种情况吗!!!! 题意似乎有问题 题目描述 树可以用来表 ...
- 【树链剖分】洛谷P3379 树链剖分求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
随机推荐
- [日常] crontab的秒执行和串行化和多进程实现
1. crontab的最低运行频率是,按照每分钟执行一次,通过在脚本中简单实现按秒级别运行 比如这条cron规则 , 每分钟执行一次脚本 * * * * * php /var/www/html/tes ...
- Eclipse下安装SVN插件以及连接SVN服务并发布项目
Eclipse安装SVN插件 Help->Eclipse MarketPlace 查找并安装Subclipse插件 按默认步骤完成SVNEclipse插件的安装(安装完成后需要重启Eclipse ...
- 十七、curator recipes之DistributedPriorityQueue
简介 官方文档:http://curator.apache.org/curator-recipes/distributed-priority-queue.html javaDoc:http://cur ...
- Java使用Redisson分布式锁实现原理
本篇文章摘自:https://www.jb51.net/article/149353.htm 由于时间有限,暂未验证 仅先做记录.有大家注意下哈(会尽快抽时间进行验证) 1. 基本用法 添加依赖 &l ...
- 商城项目,java返回json数据,报错406
前言: 项目结构为maven,搭建好架构,整合ssm,进行测试, 从数据库中查询数据,返回json数据,结果报错406 问题: 解决: 1,确定项目中json包是否存在(极大可能出于此) 2,处理器适 ...
- nylg 开方数
开方数 时间限制:500 ms | 内存限制:65535 KB 难度:3 描述 现在给你两个数 n 和 p ,让你求出 p 的开 n 次方. 输入 每组数据包含两个数n和p.当n和p都为0 ...
- 海量数据中找出前k大数(topk问题)
海量数据中找出前k大数(topk问题) 前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小 ...
- VMware安装vnwaretools
1. 在VMware Fusion 6.0.4下安装Ubuntu镜像:ubuntu-14.04.1-desktop-amd64.iso 2. 点击虚拟机菜单栏-安装VMware Tools 3. 进入 ...
- Laravel 支付宝支付异步通知
支付宝支付通知有前端通知(GET)和服务器异步通知(POST) 在配置支付宝支付时,需要注意的问题就是支付宝的回调操作: 1.在laravel中应该将支付宝通知路径组织csrf验证,否则会导致419错 ...
- 如何使用CSS进行网页布局(HTML/CSS)
什么叫做布局? 又称为版式布局,是网页UI设计师将有限的视觉元素进行有机的排列组合. 题目:假设高度已知,请写出三栏布局,其中左栏和右栏宽度各为300px,中间自适应 1.浮动布局 <!DOCT ...