【模板】线段树 1

题目描述

如题,已知一个数列,你需要进行下面两种操作:

1.将某区间每一个数加上x

2.求出某区间每一个数的和

输入输出格式

输入格式:

第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

接下来M行每行包含3或4个整数,表示一个操作,具体如下:

操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

输出格式:

输出包含若干行整数,即为所有操作2的结果。

#include<iostream>
#include<cstdio>
using namespace std;
struct node{
	long long mark,sum;
}tree[400010];
int x[100010];
int n,m,a,b,c;
int as;
int sx,st,sk;
long long ans;
char pd;
void update(int l,int r,int i)
{
	if(!tree[i].mark)
	{
		return;
	}
	int mid=(l+r)/2;
	tree[i*2].sum+=tree[i].mark*(long long)(mid-l+1);
	tree[i*2+1].sum+=tree[i].mark*(long long)(r-mid);
	tree[i*2].mark+=tree[i].mark;
	tree[i*2+1].mark+=tree[i].mark;
	tree[i].mark=0;
}
long long query(int tl,int tr,int l,int r,int i)
{
	if(tl>r||tr<l)
	{
		return 0;
	}
	if(tl<=l&&r<=tr)
	{
		return tree[i].sum;
	}
	update(l,r,i);
	int mid=(l+r)/2;
	return query(tl,tr,l,mid,i*2)+query(tl,tr,mid+1,r,i*2+1);
}
void add(int tl,int tr,int l,int r,int i,int val)
{
	if(tl>r||tr<l)
	{
		return;
	}
	if(tl<=l&&tr>=r)
	{
		tree[i].sum+=val*(long long)(r-l+1);
		tree[i].mark+=val;
		return;
	}
	update(l,r,i);
	int mid=(l+r)/2;
	add(tl,tr,l,mid,i*2,val);
	add(tl,tr,mid+1,r,i*2+1,val);
	tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
void build(int l,int r,int i)
{
	if(l==r)
	{
		tree[i].sum=x[l];
		return;
	}
	int mid=(l+r)/2;
	build(l,mid,i*2);
	build(mid+1,r,i*2+1);
	tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
void solve()
{
	build(1,n,1);
	scanf("
");
	for(int i=1;i<=m;i++)
	{
		char ch;
		int l,r,v;
		scanf("%c",&ch);
		if(ch=='2')
		{
			scanf("%d%d
",&l,&r);
			ans=query(l,r,1,n,1);
			printf("%lld
",ans);
		}
		else
		{
			scanf("%d%d%d
",&l,&r,&v);
			add(l,r,1,n,1,v);
		}
	}
}
int main()
{
	cin>>n>>m;
	for(a=1;a<=n;a++)
	{
		cin>>x[a];
	}
	solve();
//	build(1,n,1);
//	for(a=1;a<=m;a++)
//	{
//		cin>>pd;
//		if(pd=='1')
//		{
//			scanf("%d%d%d",&sx,&st,&sk);
//			add(sx,st,1,n,1,sk);
//		}
//		else
//		{
//			scanf("%d%d%d",&sx,&st);
//			ans=query(sx,st,1,n,1);
//			printf("%ld
",ans);
//		}
//	}

}


原文地址:https://www.cnblogs.com/ztz11/p/9189968.html