题解:B4566 [山东省小学组体验营 2026] 施肥

· · 题解

这个家伙很勤劳,因为它是一个题目传送门。

注意到,这是一道特别简单的差分,而且位于 T1 的宝座。于是,某位天真的 OIer 就开始啪啪啪地敲代码了。敲到一半发现了不对劲:在这道题中,每个位置增加的值是不同的,这个值随着 i 的变化而变化。

不难发现,对于 x,y,z,每次乘的值是固定的,于是推出了以下关于 x 的式子:

x_1\cdot i^2+x_2\cdot i^2+x_3\cdot i^2+\cdots+x_m\cdot i^2=(x_1+x_2+x_3+\cdots+x_m)\cdot i^2

注:以上式子的逻辑对于 y,z 同理。

所以,得出结论:我们分别对 x,y,z 进行差分,然后在原来 a_i 的基础上加上题目中的神秘小公式,每次询问的时候输出对应的值就行了。

于是,AC 代码就敲出来了:

#include<bits/stdc++.h>
#define int long long //十年 OI 一场空,不开 long long 见祖宗
#define N 100050
using namespace std;
int n,m,Q,a[N],x[N],y[N],z[N],l,r,xx,yy,zz;
signed main(){
    cin>>n>>m>>Q;
    for (int i=1; i<=n; i++){
        cin>>a[i];
    }
    while (m--){
        cin>>l>>r>>xx>>yy>>zz;
        x[l]+=xx; x[r+1]-=xx; //对 x 进行差分
        y[l]+=yy; y[r+1]-=yy; //对 y 进行差分
        z[l]+=zz; z[r+1]-=zz; //对 z 进行差分
    }
    for (int i=1; i<=n; i++){
        x[i]+=x[i-1]; y[i]+=y[i-1]; z[i]+=z[i-1];
        a[i]+=(x[i]*i*i+y[i]*i+z[i]); //加上神秘小公式
    }
    while (Q--){
        cin>>xx;
        cout<<a[xx]<<"\n"; //输出对应的值
    }
    return 0;
}

提示: