链接
线段树的入门题
打延迟标记
#include<stdio.h>
const int maxn = 1e5+10;
typedef long long LL;
struct st
{
int l,r;
LL sum;
LL add;//延迟标记
} t[maxn*4];
LL a[maxn];
void build(int p,int l,int r)
{
t[p].l = l;
t[p].r = r;
if(l == r)
{
t[p].sum = a[l];
// scanf("%d",&t[p].sum);
return ;
}
int mid = (l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].sum = t[p*2].sum+t[p*2+1].sum;
}
void spread(int p)
{
int k = p*2;
if(t[p].add)
{
t[p*2].sum += t[p].add*(t[p*2].r-t[p*2].l+1);//更新左子节点
t[k+1].sum += t[p].add*(t[k+1].r-t[k+1].l+1);
t[k].add += t[p].add;//给左子节点打标记
t[k+1].add += t[p].add;
t[p].add = 0;
}
}
void updata(int p,int l,int r,int v)
{
if(l <= t[p].l && r >= t[p].r)//完全覆盖
{
t[p].sum += (LL)(v*(t[p].r-t[p].l+1));
t[p].add += v;
return ;
}
spread(p);
int mid = (t[p].l+t[p].r)>>1;
if(l <= mid)
updata(p*2,l,r,v);
if(r > mid)
updata(p*2+1,l,r,v);
t[p].sum = t[p*2].sum+t[p*2+1].sum;
}
LL ans;
LL ask(int p,int l,int r)
{
if(l <= t[p].l && r >= t[p].r)
return t[p].sum;
spread(p);
LL val = 0;
int mid = (t[p].l+t[p].r)>>1;
if( l <= mid)
val += ask(p*2,l,r);
if(r > mid)
val += ask(p*2+1,l,r);
return val;
}
int main()
{
int n,m;
int a1,b;
char str[5];
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; ++i)
scanf("%lld",&a[i]);
build(1,1,n);
while(m--)
{
scanf("%s%d%d",str,&a1,&b);
if(str[0] == 'C')
{
int x;
scanf("%d",&x);
updata(1,a1,b,x);
}
else
{
ans = 0;
ans = ask(1,a1,b);
printf("%lld\n",ans);
}
}
return 0;
}