1 条题解

  • 0
    @ 2025-8-24 22:58:43

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Rigel
    苍山负雪,明烛天南。|| 高二现役 OIer。

    搬运于2025-08-24 22:58:43,当前版本为作者最后更新于2024-12-25 18:37:18,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    思路

    数学题。

    对于区间 [l,r][l,r],设 m=rl+1m=r-l+1,则:

    $ \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
    上传者