尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

题解:P1471 方差

题解:P1471 方差
📅 发布时间:2026/6/20 17:31:53

【题目传送门】

一眼分块能做,然后就来开始做。狠狠地做。

构造

我们考虑根号分治,对于每个块我们开:当前的数值和 \(sum1\),当前的数值平方的和 \(sum2\),当前的数值的 \(\operatorname {lazy}\) 数组。
这道题最阴险的地方是它的输入不是全部整数,但是样例给的是正整数,然后我给我数组全部开的 \(\operatorname {int}\) 类型,听取 WA 声一片。

修改

  • 我们对于散块直接暴力处理,主要是不要忘了更新 \(sum1、sum2\)。
  • 我们对于整块的处理就更加直接,直接叠加到 \(\operatorname{lazy}\) 里面就好。

平均值查询

通过 \(sum1+tag\times len\) 直接可以得出。

方差查询

我们要开始推式子了。
我们求方差的式子是:

\[\begin{equation} \begin{split} len=r-l+1,\\ s^2&=\frac{\sum^{r}_{i=l}(\ x_i\ -\bar{\ x\ })^2}{len} \\&=\frac{\sum^{r}_{i=l}(x_i^2\ -\ 2\cdot\bar{\ x\ }\cdot x_i\ +\ \bar{\ x\ }^2)}{len}\\&=\frac{\sum^{r}_{i=l}x_i^2}{len}\ -2\cdot\bar{\ x\ }\cdot\frac{\sum^{r}_{i=l}x_i}{len}\ +\ \bar{\ x\ }\cdot\frac{\sum^{r}_{i=l}\bar{\ x\ }}{len}\\&=\frac{\sum^{r}_{i=l}x_i^2}{len}\ -2\cdot\bar{\ x\ }^2\ +\ \bar{\ x\ }^2\\&=\frac{\sum^{r}_{i=l}x_i^2}{len}\ -\bar{\ x\ }^2 \end{split} \end{equation} \]

也就是我们要知道某个区间的方差只需要知道改区间的平方和以及平均数就好了,显然,平均数可以直接套用操作 \(1\) 前面我们写的代码。
我们由于这个 \(lazy\_tag\) (下称 \(tag\))存在,显然不是很好直接处理这个平方和的式子,但是不用 \(tag\) 又不行,那我们只能继续推式子寻找破局之道了(这里的 \(tag\) 设为 \(k\)):

\[\begin{equation} \begin{split} sum^2&=\sum_{i=l}^{r}(x_i+k)\\&=\sum^{r}_{i=l}x_i^2\ +\ 2k\cdot\sum^r_{i=l}x_i\ +\ nk^2 \end{split} \end{equation} \]

秒杀,下面是代码。

\(\mathcal{CODE}\)

#include<bits/stdc++.h>
using namespace std;
#define itn int
#define reaD read
#define int long long
inline void read(int &x){x=0;int p=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')p=-1;ch=getchar();}while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}x*=p;
}
void write(int x){if(x<0){putchar('-');x*=-1;}if(x<10){putchar(x+48);return;}write(x/10);putchar(x%10+48);
}
const int N=1e5+1000,M=800;
int n,m,pos[N],L[M],R[M],cnt,len;
double tag[M],sum1[M],sum2[M],a[N];void init(){len=(int)sqrt(n);cnt=(n-1)/len+1;for(int i=1;i<=n;i++){pos[i]=(i-1)/len+1;}for(int i=1;i<=cnt;i++){L[i]=(i-1)*len+1;R[i]=min(n,i*len);for(int j=L[i];j<=R[i];j++){sum1[i]+=a[j];sum2[i]+=a[j]*a[j];}}
}void catter(int l,int r,double c){for(int i=l;i<=r;i++){sum2[pos[l]]+=(a[i]+c)*(a[i]+c)-a[i]*a[i];a[i]+=c;}sum1[pos[l]]+=1.0*(r-l+1)*c;
}void pre_block(int id,double c){tag[id]+=c;
}void update(int l,int r,double c){if(pos[l]==pos[r]){catter(l,r,c);return;}catter(l,R[pos[l]],c);catter(L[pos[r]],r,c);for(int i=pos[l]+1;i<pos[r];i++){pre_block(i,c);}return;
}double query_catter1(int l,itn r){double res=0;for(int i=l;i<=r;i++){res+=a[i];}res+=(r-l+1)*tag[pos[l]];return res;
}double query_block1(int id){double res=0;res+=sum1[id];res+=(R[id]-L[id]+1)*tag[id];return res;
}double query1(int l,int r){if(pos[l]==pos[r]){double res=query_catter1(l,r);return 1.0*res/(r-l+1);}double res=0;res+=query_catter1(l,R[pos[l]]);res+=query_catter1(L[pos[r]],r);for(int i=pos[l]+1;i<pos[r];i++){res+=query_block1(i);}return res/(r-l+1);
}double query_catter2(int l,int r){double res=0;for(int i=l;i<=r;i++){res+=(a[i]+tag[pos[l]])*(a[i]+tag[pos[l]]);}return res;
}double query_block2(int id){double res=0;res+=sum2[id];res+=2*tag[id]*sum1[id];res+=(1.0*R[id]-L[id]+1)*tag[id]*tag[id];return res;
}double query2(int l,int r){if(pos[l]==pos[r]){double res1=query_catter2(l,r);double res2=query_catter1(l,r);// cout<<"res1:"<<res1<<" res2:"<<res2<<endl;double ans=1.0*res1/(r-l+1);ans-=(res2/(r-l+1))*(res2/(r-l+1));return ans;}double res1=0,res2=0;res1+=query_catter2(l,R[pos[l]]);res1+=query_catter2(L[pos[r]],r);res2+=query_catter1(l,R[pos[l]]);res2+=query_catter1(L[pos[r]],r);for(int i=pos[l]+1;i<pos[r];i++){res1+=query_block2(i);res2+=query_block1(i);}double ans=res1/(r-l+1);ans-=(res2/(r-l+1))*(res2/(r-l+1));// cout<<"res1:"<<res1<<" res2:"<<res2<<endl;return ans;
}main(void){// ios::sync_with_stdio(false);// cin.tie(nullptr);// cout.tie(nullptr);read(n);read(m);for(int i=1;i<=n;i++){cin>>a[i];}// for(int i=1;i<=n;i++){// printf("%.2lf\n",a[i]);// }init();for(int i=1,top,l,r;i<=m;i++){read(top);double c;if(top==1){read(l);read(r);cin>>c;update(l,r,c);}if(top==2){read(l);read(r);printf("%.4lf\n",query1(l,r));}if(top==3){read(l);read(r);printf("%.4lf\n",query2(l,r));}}
}

相关新闻

  • 2025 年 11 月中国水泵厂家权威推荐榜:消防/多级/自吸/磁力/排污/真空/离心/卧式水泵全品类实力解析与高效选购指南
  • AI时代资料收录的理论建构与实践逻辑
  • Gerrit新增标签

最新新闻

  • MCM06型长跨距重载双滑块模组技术详解
  • Java Stream collect() 原理与高阶实战:从分组统计到自定义聚合
  • DSP56800E调试实战:CodeWarrior内存、寄存器与EOnCE硬件断点深度解析
  • 轻量级消息驱动AI助手Hermes:30分钟Railway部署实战
  • G-Helper深度解析:如何用开源工具彻底解放华硕笔记本性能潜力
  • 青岛闲置旧金变现渠道,2026市南崂山靠谱回收店全城上门当场结款 - 名奢变现站

日新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号