题意:
区间更新,直接上线段树。
题外话:
这道题虽然水,但是让我了解到了线段树的区间加值是怎么操作的。
#include<stdio.h>
#include<string.h>
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r
const int MAXN=100000+5;
long long int a[MAXN],t[MAXN*4],mark[MAXN*4];
void build(int root,int l,int r)
{
mark[root]=0;
if(l==r)
t[root]=a[l];
else{
int mid=(l+r)/2;
build(lson);
build(rson);
t[root]=t[root<<1]+t[root<<1|1];
}
}
void pushdown(int root,int m)
{
if(mark[root])
{
mark[root<<1]+=mark[root];
mark[root<<1|1]+=mark[root];
//下面两行是区间更新的要点。直接让区间值加上之前更新的价值*区间长度。
t[root<<1]+=mark[root]*(m-m/2);//因为是分给两个区间,要划分一下
t[root<<1|1]+=mark[root]*(m/2);
mark[root]=0;
}
}
void update(int root,int l,int r,int L,int R,long long int x)
{
if(r<L||R<l)
return ;
if(L<=l&&r<=R)
{
t[root]+=(r-l+1)*x;
mark[root]+=x;
return ;
}
pushdown(root,r-l+1);
int mid=(l+r)/2;
if(L<=mid)
update(lson,L,R,x);
if(mid<R)
update(rson,L,R,x);
t[root]=t[root<<1]+t[root<<1|1];
}
long long int query(int root,int l,int r,int L,int R)
{
long long int ans=0;
if(r<L||R<l)
return 0;
if(L<=l&&r<=R)
return t[root];
pushdown(root,r-l+1);
// printf("%lld\n",t[root]);
int mid=(l+r)/2;
if(mid>=L)
ans=ans+query(lson,L,R);
if(mid<R)
ans=ans+query(rson,L,R);
t[root]=t[root<<1]+t[root<<1|1];
// printf("%lld\n",ans);
return ans;
}
int main()
{
int n,m,i;
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
while(m--)
{
char s[2];
scanf("%s",&s);
int x,y;
long long z;
if(s[0]=='Q')
{
scanf("%d%d",&x,&y);
printf("%lld\n",query(1,1,n,x,y));
}
else if(s[0]=='C')
{
scanf("%d%d%lld",&x,&y,&z);
update(1,1,n,x,y,z);
}
}
}
}
本文详细介绍了如何使用线段树进行区间更新操作,并通过一个具体的实现案例来展示这一过程。主要内容包括线段树的基本构建、区间更新及查询的具体实现方式。
409

被折叠的 条评论
为什么被折叠?



