题目大意


你有n个整数,A1、A2、…、AN。你需要处理两种操作。

  • 将给定范围内的每个数字加上一个给定的值。
  • 求一个给定范围内的数字的总和。

思路


线段树成段增减的模板题。

代码


#include<iostream>
#include<stdio.h>
using namespace std;
#define MAXSIZE 100000
int total_edge,val[MAXSIZE+1];
struct node
{
	long long total;
	//区间属性,这里是total,表示区间元素和。 
	int left;
	int right;
	long long mark;
	//mark表示延迟标记 
}tree[MAXSIZE*3];
long long create(int root,int left,int right)
//以root为根节点建树。 
{
	tree[root].mark=0;
	tree[root].left=left;
	tree[root].right=right;
	if(left==right)
		return tree[root].total=val[left];
	int middle=(left+right)/2;
	return tree[root].total=create(2*root,left,middle)+create(2*root+1,middle+1,right);
}
void updata_mark(int root)
//更新root的子节点的延迟标记。 
{
	if(tree[root].mark)
	{
		tree[root].total+=tree[root].mark*(tree[root].right-tree[root].left+1);
		if(tree[root].left!=tree[root].right)
		{
			tree[root*2].mark+=tree[root].mark;
			tree[root*2+1].mark+=tree[root].mark;
		}
		tree[root].mark=0;
	}
}
long long calculate(int root,int left,int right)
//以root为根节点的线段树中,求取区间[left,right]的元素和。 
{
	updata_mark(root);
	if(tree[root].left>right||tree[root].right<left)
		return 0;
	if(left<=tree[root].left&&tree[root].right<=right)
		return tree[root].total;
	return calculate(2*root,left,right)+calculate(2*root+1,left,right);
}
long long updata(int root,int left,int right,int val)
//以root为根节点的线段树中,将区间[left,right]中的元素加上val。 
{
	updata_mark(root);
	if(tree[root].left>right||tree[root].right<left)
		return tree[root].total;
	if(left<=tree[root].left&&tree[root].right<=right)
	{
		tree[root].mark+=val;
		updata_mark(root);
		return tree[root].total;
	}
	return tree[root].total=updata(2*root,left,right,val)+updata(2*root+1,left,right,val);
}

int main()
{
	int n,q;
	while(~scanf("%d%d",&n,&q))
	{
		for(int i=1;i<=n;i++)
			scanf("%d",&val[i]);
		create(1,1,n);
		char op;
		for(int i=0;i<q;i++)
		{
			scanf("\n%c",&op);
			if(op=='Q')
			{
				int a,b;
				scanf("%d%d",&a,&b);
				printf("%I64d\n",calculate(1,a,b));
			}
			else
			{
				int a,b,c;
				scanf("%d%d%d",&a,&b,&c);
				updata(1,a,b,c);
			}
		}
	}
}