下面是以求所给区间和为例,而构建的线段树.
#include <cmath>
#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define INFINITE 0x3f3f3f
const int MAXNUM = 100000 + 5;
typedef long long ll;
struct SegTreeNode
{
ll val;
ll addMark;//延迟标记
}segTree[MAXNUM << 2];
//int arr[MAXNUM];
void pushup(ll x)//向上回溯
{
segTree[x].val=segTree[x<<1].val+segTree[x<<1|1].val;
}
void build(ll root,ll istart, ll iend)
{
segTree[root].addMark=0;//将延迟标记初始化
if(istart == iend)//当是叶子节点时输入初值
{
scanf("%lld",&segTree[root].val);
return;
}
ll mid = (istart + iend) >> 1;//利用二分思想构建线段树
build(root << 1, istart, mid);
build(root << 1|1, mid+1, iend);
pushup(root);//回溯
}
void pushdown(ll x,ll l,ll r)//将延迟标记向下传递
{
if(segTree[x].addMark != 0)
{
segTree[x<<1].addMark += segTree[x].addMark;
segTree[x<<1|1].addMark += segTree[x].addMark;
segTree[x<<1].val += segTree[x].addMark*((l+r)/2-l+1);
segTree[x<<1|1].val += segTree[x].addMark*(r-(l+r)/2);
segTree[x].addMark = 0;
}
}
ll query(ll root,ll nstart,ll nend,ll qstart,ll qend)//查找
{
if(qstart<=nstart && qend>=nend)
return segTree[root].val;
if(nend==nstart)
return 0;
pushdown(root,nstart,nend);
ll mid = (nstart + nend) >> 1;
ll maxx=0;
if(qend <= mid)
{
maxx=query(root << 1,nstart,mid,qstart,qend);
}
else if(qstart>mid)
{
maxx=query(root << 1|1,mid+1,nend,qstart,qend);
}
else
{
maxx += query(root*2,nstart,mid,qstart,qend);
maxx += query(root*2+1,mid+1,nend,qstart,qend);
}
return maxx;
}
//如果是单点更新,ustart,uend,addval,变为,index,addval,单点更新,即,区间为[index,index];
//是区间更新的一个变种.
void updateOne(ll root, ll nstart,ll nend, ll ustart, ll uend,ll addval)//更新
{
if(ustart>nend||uend<nstart)//如果要查找的区间不在当前区间内,返回
return;
if(ustart<=nstart&&nend<=uend)
{
segTree[root].val += addval*(nend-nstart+1);
segTree[root].addMark += addval;
return;
}
//if(nend==nstart)
//return;
pushdown(root,nstart,nend);
ll mid = (nstart + nend) >> 1;
if(ustart>mid)
updateOne(root << 1 | 1,mid+1,nend,ustart,uend,addval);
else if(uend<=mid)
updateOne(root << 1,nstart,mid,ustart,uend,addval);
else
{
updateOne(root << 1,nstart,mid,ustart,uend,addval);
updateOne(root << 1 | 1,mid+1,nend,ustart,uend,addval);
}
pushup(root);
}
int main()
{
ll n,m;
scanf("%lld%lld",&n,&m);
//memset(arr,0,sizeof(arr));
build(1,1,n);//建树
ll x,y,c;
char q;
while(m--)
{
scanf(" %c",&q);
if(q=='Q')
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,1,n,x,y));
}
if(q=='C')
{
scanf("%lld%lld%lld",&x,&y,&c);
updateOne(1,1,n,x,y,c);//更新
}
}
return 0;
}