poj3468 Simple Problem with Integers (线段树)

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input <dl><dd>

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

</dd> Output <dd>

You need to answer all Q commands in order. One answer in a line.

</dd> Sample Input <dd>
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
</dd> Sample Output <dd>
4
55
9
15
</dd> Hint <dd>
The sums may exceed the range of 32-bit integers.
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
using namespace std;

struct node
{
	long long int  num;
	long long int left, right,mark;
};

node shu[2000000];

void creatshu(long long int l,long long int r,int i)
{
	shu[i].left = l;
	shu[i].right = r;
	shu[i].mark = 0;
	shu[i].num = 0;
	if (l==r)
	{
		scanf("%lld", &shu[i].num);
		return;
	}
	long long int mid = (l + r) / 2;
	creatshu(l, mid, i * 2);
	creatshu(mid + 1, r, i * 2 + 1);
	shu[i].num = shu[i * 2].num + shu[i * 2 + 1].num;
	return;
}

void pushnext(long long mark, int i)
{
	shu[i].mark += mark;
	shu[i].num += (shu[i].right - shu[i].left + 1)*mark;
}

void add(long long int l,long long  int r, long long int mark, int i)
{
	if (shu[i].left == l && shu[i].right == r)
	{
		shu[i].num += (shu[i].right - shu[i].left + 1)*mark;
		shu[i].mark += mark;
	}
	else
	{
		long long int mid = (shu[i].left + shu[i].right) / 2;
		/*if (shu[i].mark != 0)
		{
			add(shu[i].left, mid, shu[i].mark, i * 2);
			add(mid+1, shu[i].right, shu[i].mark, i * 2 + 1);
			shu[i].mark = 0;
		}*/
		if (shu[i].mark != 0)
		{
			pushnext(shu[i].mark, i * 2);
			pushnext(shu[i].mark, i * 2 + 1);
			shu[i].mark = 0;
		}
		 shu[i].num += (r - l + 1)*mark;
		if (r <= mid)
		{
			add(l,r, mark, i * 2);
		}
		else if (l > mid)
		{
			add(l,r, mark, i * 2 + 1);
		}
		else if (l <= mid && r > mid)
		{
			add(l, mid, mark, i * 2);
			add(mid + 1, r, mark, i * 2 + 1);
		}
	}
}




long long int search(long long int l,long long int r,int i)
{
	if (shu[i].left == l && shu[i].right == r)
	{
		return shu[i].num; 
	}
	else
	{
		long long int mid = (shu[i].left + shu[i].right) / 2;
	 /*f (shu[i].mark!=0)
	 {
		 if (r <= mid)
		 {
			 add(l, r, shu[i].mark, i * 2);
		 }
		 else if (l > mid)
		 {
			 add(l, r, shu[i].mark, i * 2 + 1);
		 }
		 else if (l <= mid && r > mid)
		 {
			 add(l, mid, shu[i].mark, i * 2);
			 add(mid + 1, r, shu[i].mark, i * 2 + 1);
		 }
		 shu[i].mark = 0;
	 }*/
			if (shu[i].mark != 0)
			{
				pushnext(shu[i].mark, i * 2);
				pushnext(shu[i].mark, i * 2 + 1);
				shu[i].mark = 0;
			}
		if (r <= mid)
		{
			return search(l, r, i * 2);
		}
		else if (l > mid)
		{
			return search(l, r, i * 2 + 1);
		}
		else if (l <= mid && r > mid)
		{
			return search(l, mid, i * 2)+search(mid+1,r,i*2+1);
			
		}
	}
}

int main()
{
	long long int len, ordernum;
	while (~scanf("%lld %lld", &len, &ordernum))
	{
		creatshu(1, len, 1);
		char order[100];
		long long int left, right,mark;
		for (int i = 0; i < ordernum; i++)
		{
			scanf("%s", order);
			if (order[0] == 'Q')
			{
				scanf("%lld %lld", &left, &right);
				printf("%lld\n", search(left, right, 1));
			}
			
			else if (order[0] == 'C')
			{
				scanf("%lld %lld %lld", &left, &right, &mark);
				add(left, right, mark, 1);
			}
		}
	}
	return 0;
}

//by swust_t_p
</dd></dl>
全部评论

相关推荐

点赞 评论 收藏
分享
听说改名字就能收到offer哈:Radis写错了兄弟
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务