题目大意:维护一个有 N 个元素的序列,支持以下操作:区间加,区间询问均值,区间询问方差。

题解:可知区间均值和区间和有关,即:维护区间和就等于维护了区间均值。区间方差表达式为 $$\frac{\Sigma_{i=1}n(a[i]-aver)2}{n}$$,化简之后可知还需维护区间的平方和。

这道题说明了,对于线段树来说,维护的东西并不一定直接是需要维护的东西,可以维护一些间接的信息,最后综合到一起计算得到需要维护的答案。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10; int n,q;
double a[maxn]; struct node{int lc,rc;double tag,sum,sum2;};
struct segment_tree{
#define ls t[k].lc
#define rs t[k].rc
node t[maxn<<1];
int tot;
segment_tree():tot(1){memset(t,0,sizeof(t));}
inline void pushup(int k){
t[k].sum=t[ls].sum+t[rs].sum;
t[k].sum2=t[ls].sum2+t[rs].sum2;
}
inline void pushdown(int k,int l,int r){
int mid=l+r>>1;
t[ls].sum2+=(mid-l+1)*t[k].tag*t[k].tag+2*t[k].tag*t[ls].sum;
t[ls].sum+=(mid-l+1)*t[k].tag;
t[ls].tag+=t[k].tag;
t[rs].sum2+=(r-mid)*t[k].tag*t[k].tag+2*t[k].tag*t[rs].sum;
t[rs].sum+=(r-mid)*t[k].tag;
t[rs].tag+=t[k].tag;
t[k].tag=0;
}
void build(int k,int l,int r){
if(l==r){t[k].sum=a[l],t[k].sum2=a[l]*a[l];return;}
int mid=l+r>>1;
ls=++tot,build(ls,l,mid);
rs=++tot,build(rs,mid+1,r);
pushup(k);
}
void modify(int k,int l,int r,int x,int y,double val){
if(l==x&&r==y){
t[k].sum2+=2*val*t[k].sum+(r-l+1)*val*val;
t[k].sum+=(r-l+1)*val;
t[k].tag+=val;
return;
}
int mid=l+r>>1;
pushdown(k,l,r);
if(y<=mid)modify(ls,l,mid,x,y,val);
else if(x>mid)modify(rs,mid+1,r,x,y,val);
else modify(ls,l,mid,x,mid,val),modify(rs,mid+1,r,mid+1,y,val);
pushup(k);
}
double query1(int k,int l,int r,int x,int y){
if(l==x&&r==y)return t[k].sum;
int mid=l+r>>1;
pushdown(k,l,r);
if(y<=mid)return query1(ls,l,mid,x,y);
else if(x>mid)return query1(rs,mid+1,r,x,y);
else return query1(ls,l,mid,x,mid)+query1(rs,mid+1,r,mid+1,y);
}
double query2(int k,int l,int r,int x,int y){
if(l==x&&r==y)return t[k].sum2;
int mid=l+r>>1;
pushdown(k,l,r);
if(y<=mid)return query2(ls,l,mid,x,y);
else if(x>mid)return query2(rs,mid+1,r,x,y);
else return query2(ls,l,mid,x,mid)+query2(rs,mid+1,r,mid+1,y);
}
double mean(int l,int r){return this->query1(1,1,n,l,r)/(r-l+1);}
double var(int l,int r){
double tmp=this->mean(l,r);
double tmp2=this->query2(1,1,n,l,r);
return tmp2/(r-l+1)-tmp*tmp;
}
}sgt; void read_and_parse(){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)scanf("%lf",&a[i]);
sgt.build(1,1,n);
} void solve(){
int opt,x,y;
double k;
while(q--){
scanf("%d",&opt);
if(opt==1){
scanf("%d%d%lf",&x,&y,&k);
sgt.modify(1,1,n,x,y,k);
}else if(opt==2){
scanf("%d%d",&x,&y);
printf("%.4lf\n",sgt.mean(x,y));
}else if(opt==3){
scanf("%d%d",&x,&y);
printf("%.4lf\n",sgt.var(x,y));
}
}
} int main(){
read_and_parse();
solve();
return 0;
}

【洛谷P1471】方差的更多相关文章

  1. 洛谷 P1471 方差

    洛谷 P1471 方差 题目背景 滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的 ...

  2. 洛谷P1471 方差

    蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差. ——by 洛谷; http://www.luogu.org/problem/show?pid=1 ...

  3. 洛谷——P1471 方差

    P1471 方差 题目描述 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差. 借一下远航之曲大佬的图片,特别清晰: 那么只要维护区间平方和,就可以 ...

  4. 2018.08.16 洛谷P1471 方差(线段树)

    传送门 线段树基本操作. 把那个方差的式子拆开可以发现只用维护一个区间平方和和区间和就可以完成所有操作. 同样区间修改也可以简单的操作. 代码: #include<bits/stdc++.h&g ...

  5. AC日记——方差 洛谷 P1471

    方差 思路: 线段树: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 struct TreeN ...

  6. 【洛谷】【线段树】P1471 方差

    [题目背景:] 滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西. [题目描述:] 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差 ...

  7. 洛谷P4072 [SDOI2016]征途(带权二分,斜率优化)

    洛谷题目传送门 一开始肯定要把题目要求的式子给写出来 我们知道方差的公式\(s^2=\frac{\sum\limits_{i=1}^{m}(x_i-\overline x)^2}{m}\) 题目要乘\ ...

  8. 洛谷NOIp热身赛题解

    洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...

  9. 洛谷 P4072 [SDOI2016]征途 斜率优化DP

    洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...

随机推荐

  1. 20155235 《网络攻防》 实验五 MSF基础应用

    20155235 <网络攻防> 实验五 MSF基础应用 实验内容 一个主动攻击实践,如ms08_067; (1分) 一个针对浏览器的攻击,如ms11_050:(1分) 一个针对客户端的攻击 ...

  2. 【php增删改查实例】第八节 - 部门管理模块(编写PHP程序)

    首先,在同级目录新建一个query.php文件: 接着,去刷新页面,打开F12,NetWork,看看当前的请求能不能走到对应的php文件? 这就说明datagrid确实能够访问到query.php 只 ...

  3. 使用fddb的测试工具测试自己的检测器

    本文是在linux下测试的,首先编译,并安装gnuplot 按照程序给定,将文件放置到对应的文件夹下 #runEvaluate.pl # where gnuplot ismy $GNUPLOT = & ...

  4. Selenium-ActionChainsApi接口详解

    ActionChains 有时候我们在通过Selenium做UI自动化的时候,明明能够在DOM树内看到这个元素,但是我在通过driver click.sendkey的时候,就是点击不到或无法输入字符串 ...

  5. 6.Xilinx RapidIO核仿真与包时序分析

    转自https://www.cnblogs.com/liujinggang/p/10123498.html 一.软件平台与硬件平台 软件平台: 操作系统:Windows 8.1 64-bit 开发套件 ...

  6. java 调用 linux 命令行 +使用管道、awk等命令进行数据处理的方法

    这里用 sh -c "命令" 的方式是因为java里只能这么用,管道这边java处理不了,所以只能一次执行一条命令,但是在linux里用 sh -c 的方式返回的awk处理过的结果 ...

  7. 微信小程序之 动画 —— 自定义底部弹出层

    wxml: <view class='buy' bindtap='showBuyModal'>立即购买</view> <!-- 点击立即购买 弹出购买遮罩层 --> ...

  8. Salesforce随笔: 解决被指定给Chatter相关用户的RecordType无法被删除的问题

    被指定给以下三组用户的RecordType无法在对应的Profile里取消占用: Chatter External User Chatter Free User Chatter Moderator U ...

  9. Win环境 Android Studio使用Git 教程 ( 生成SSH key )

    Github和码云都提供SSH协议,即用户可以用公钥认证方式连接到码云的SSH服务器.这就需要生成并部署SSH Key.下面就是我生成SSH Key的步骤,希望有所帮助: Git生成SSH key 在 ...

  10. python之GIL理解

    GIL(Global Interpreter Lock) 全局解释器锁 python3中是假的多线程,它不是真正的并行,是利用了cpu上下文的切换而已.同一时间只能有一个线程使用共享数据,其它线程处于 ...