关键在于创建一个向上返回的函数up,向下查询的同时将父亲sum和add值传给儿子函数down
最后用lazy函数更新sum和add的值
先通过build函数是sum数组完成初始化,然后用adds已经quiey函数完成求解,详细注释见代码
#include<iostream>
#include<cstdio>
using namespace std;
int m,n;
const int maxn=100001;
long long arr[maxn];
long long sum[maxn<<2];
long long add[maxn<<2];
void up(int i)//向上返回之后更新sum的值
{
sum[i]=sum[i<<1]+sum[i<<1|1];
}
void lazy(int i,long long v,int n)//n为线段长度,v为要加入的数,i为当前下标
{
sum[i]+=v*n;
add[i]+=v;
}
void down(int i,int ln,int rn)//向下走,一边构建add数组,一边使它清空
{
if(add[i]!=0){
lazy(i<<1,add[i],ln);//传入父亲的add[i]值,使儿子的add值继承父亲的add值,之后将父亲的add值清空
lazy(i<<1|1,add[i],rn);//儿子的数组值比父亲大所以<<1表示儿子,
add[i]=0;
}
}
void build(int l,int r,int i)//创建sum数组使之完成初始化
{
if(l==r) sum[i]=arr[l];//在最底下时arr的值为sum的值
else{
int mid=(l+r)>>1;
build(l,mid,i<<1);
build(mid+1,r,i<<1|1);
up(i);//由下而上构建sum数组,构建完之后将
}
//add[i]=0;//这一步可以不要,前面没有用上
}
long long query(int jobl, int jobr, int l, int r, int i) {//查询区间内的和
if (jobl <= l && r <= jobr) {//当前区间被要进行操作的区间完全包含,直接求和;
return sum[i];
}
int mid = (l + r) >> 1;
down(i, mid - l + 1, r - mid);//向下查询,重新构建儿子的sum,以便等到被完全包含时直接返回sum的值
long long ans = 0;
if (jobl <= mid) {//未被完全包含时一直向下查询
ans += query(jobl, jobr, l, mid, i << 1);//此时ans只需要层层递归加上被完全包住的sum值,同时配合down,将父亲的sum分别分给儿子
}
if (jobr > mid) {
ans += query(jobl, jobr, mid + 1, r, i << 1 | 1);
}//若未被完全包含,将两边的子节点不断往下查,并且将和加到ans中
return ans;
}
void adds(int jobl,int jobr,long long jobv,int l,int r,int i)//对范围进行操作
{
if(jobl<=l&&jobr>=r)//当前区间被要进行操作的区间完全包含
{
lazy(i,jobv,r-l+1);
}
else{
int mid=(l+r)>>1;
down(i,mid-l+1,r-mid);
if(jobl<=mid)
{
adds(jobl,jobr,jobv,l,mid,i<<1);
}
if(jobr>mid)
{
adds(jobl,jobr,jobv,mid+1,r,i<<1|1);
}
up(i);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&arr[i]);
}
build(1,n,1);
int op;
int jobl,jobr;//要查询的左右界
long long jobv;
for(int i=1;i<=m;i++)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%d%lld",&jobl,&jobr,&jobv);
adds(jobl,jobr,jobv,1,n,1);
}
else
{
scanf("%d%d",&jobl,&jobr);
printf("%lld\n",query(jobl,jobr,1,n,1));
}
}
return 0;
}
标签:洛谷,int,sum,mid,long,down,maxn,p3372,模板
From: https://blog.csdn.net/yj0729/article/details/144558195