线段树模板

区间更新,区间查询(单点更新,区间查询懒得写了,修改一下insert参数吧)code:

#include<iostream> 
#include<cstring>
#include<cstdio>
using namespace std;
struct hp{
	long long value;
}node[800001];
int n,m;
long long ans;
long long a[200001]={0},delta[2000001]={0};
void updata(int i)
{
	node[i].value=node[i*2].value+node[i*2+1].value;
}
void paint(int i,long long a,int l,int r)
{
	node[i].value+=a*(r-l+1);
	delta[i]+=a;
}
void pushdown(int i,int l,int r)
{
	int mid; mid=(l+r)/2;
	paint(i*2,delta[i],l,mid);
	paint(i*2+1,delta[i],mid+1,r);
	delta[i]=0;
}
void build(int i,int l,int r)
{
	if (l==r)
	  {
	    node[i].value=a[l];
	    return;
	  }
	build(i*2,l,(l+r)/2);
	build(i*2+1,(l+r)/2+1,r);
	updata(i);
}
void query(int i,int l,int r,int x,int y)
{
	int mid;
	if ((x<=l)&&(y>=r))
	  {
	    ans+=node[i].value;
	    return;
	  } 
	if  (delta[i]!=0)
	pushdown(i,l,r);
	mid=(l+r)/2;
	if (x<=mid) query(i*2,l,mid,x,y);
	if (y>mid) query(i*2+1,mid+1,r,x,y);
}
void insert(int i,int l,int r,int x,int y,int z)
{
	int mid;
	if ((x<=l)&&(y>=r))
	  {
	    paint(i,z,l,r);
	    return;
	  }
	pushdown(i,l,r); mid=(l+r)/2;
	if (x<=mid)
	  insert(i*2,l,mid,x,y,z);
	if (y>mid)
	  insert(i*2+1,mid+1,r,x,y,z);
	updata(i);
}
int main()
{
	int i,kind,j,x,y;
	long long z;
	memset(delta,0,sizeof(delta));
	scanf("%d",&n);
	for (i=1;i<=n;++i)
	  scanf("%d",&a[i]);
	build(1,1,n);
	scanf("%d",&m);
	for (i=1;i<=m;++i)
	  {
	    scanf("%d",&kind);
		if (kind==1)
		  {
		    scanf("%d%d%lld",&x,&y,&z);
		    insert(1,1,n,x,y,z);
		  }  
		if (kind==2)
		  {
		  	scanf("%d",&x,&y);
		    ans=0;
		    query(1,1,n,x,y);
		    printf("%d\n",ans);
		  }
	  } 
}


你可能感兴趣的:(线段树模板)