1 条题解
-
0
自动搬运
来自洛谷,原作者为

Rigel
苍山负雪,明烛天南。|| 高二现役 OIer。搬运于
2025-08-24 22:58:43,当前版本为作者最后更新于2024-12-25 18:37:18,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
思路
数学题。
对于区间 ,设 ,则:
$ \begin{aligned} m^2s^2&=m\sum\limits_{i=l}^{r}(a_i-\overline{a})^2\\ &=m\sum\limits_{i=l}^{r}(a_i^2-2a_i\overline{a}+\overline{a}^2)\\ &=m\left(\sum\limits_{i=l}^{r}a_i^2-2\sum\limits_{i=l}^{r}a_i\overline{a}+\sum\limits_{i=l}^{r}\overline{a}^2\right)\\ &=m\left(\sum\limits_{i=l}^{r}a_i^2-\frac{2}{m}\left(\sum\limits_{i=l}^{r}a_i\right)^2+\frac{1}{m}\left(\sum\limits_{i=l}^{r}a_i\right)^2\right)\\ &=m\sum\limits_{i=l}^{r}a_i^2-2\left(\sum\limits_{i=l}^{r}a_i\right)^2+\left(\sum\limits_{i=l}^{r}a_i\right)^2\\ &=m\sum\limits_{i=l}^{r}a_i^2-\left(\sum\limits_{i=l}^{r}a_i\right)^2. \end{aligned} $
不难发现,维护区间和与区间平方和即可。
利用前缀和维护区间和与区间平方和。查询时,利用
upper_bound()找到完全包含查询区间的区间,计算区间和与区间平方和,分别减去两边多余的部分,最后计算方差。代码
取模使用
modint。特别地,
l数组与r数组应存储原始值。#include<bits/stdc++.h> #define int long long #define TT 998244353 #define M(x) (modint){x} #define maxm 200010 using namespace std; int n,m,q,l[maxm],r[maxm]; struct modint{ int v; bool operator<(const modint &b)const{return v<b.v;} modint operator+(const modint &b)const{return (modint){(v+b.v)%TT};} modint operator-(const modint &b)const{return (modint){((v-b.v)%TT+TT)%TT};} modint operator*(const modint &b)const{return (modint){(v*b.v)%TT};} }b[maxm],s1[maxm],s2[maxm],ans; inline int read(){ int ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')ret=ret*10+(ch&15),ch=getchar(); return ret*f; } signed main(){ n=read(),m=read(),q=read(); for(int i=1;i<=m;i++)l[i]=read(),r[i]=read(),b[i].v=read()%TT; for(int i=1;i<=m;i++){ s1[i]=s1[i-1]+b[i]*M((r[i]-l[i]+1)%TT); s2[i]=s2[i-1]+b[i]*b[i]*M((r[i]-l[i]+1)%TT); } while(q--){ modint S1={0},S2={0}; int x=read(),y=read(); int L=upper_bound(l+1,l+m+1,x)-l-1; int R=upper_bound(l+1,l+m+1,y)-l-1; if(L<=R){ S1=S1+s1[R]-s1[L-1]; S2=S2+s2[R]-s2[L-1]; } if(l[L]!=x){ S1=S1-b[L]*M((x-l[L])%TT); S2=S2-b[L]*b[L]*M((x-l[L])%TT); } if(r[R]!=y){ S1=S1-b[R]*M((r[R]-y)%TT); S2=S2-b[R]*b[R]*M((r[R]-y)%TT); } ans=M((y-x+1)%TT)*S2-S1*S1; printf("%lld\n",ans.v); } return 0; }
- 1
信息
- ID
- 9977
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者