POJ - 3468 A Simple Problem with Integers

A Simple Problem with Integers

Time Limit: 5000MS Memory Limit: 131072K
Total Submissions: 156222 Accepted: 48325
Case Time Limit: 2000MS
Description

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

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.

Output

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

Sample Input

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
Sample Output

4
55
9
15
Hint

The sums may exceed the range of 32-bit integers.
Source

POJ Monthly–2007.11.25, Yang Yi
线段树裸题

#include<iostream>
#include<stdio.h>
#define ll long long
using namespace std;

struct node{
	ll left,right,lazy;
	ll value;
	void change(ll num)
	{
		value = value + (right - left + 1) * num;
		if (left != right) lazy += num;//如果不是叶子节点就加上父级的lazy 
		else lazy = 0;//如果是叶子节点就直接改变节点的值,没有lazy标志 
	}
	int mid()
	{
		return (right - left) / 2 + left;
	}
};

int a[100001] = {};

struct segtree{
	node tree[400001];
	
	void bulid(int st,int ed,int x)	
	{
		tree[x].left = st;
		tree[x].right = ed;
		if (st == ed)
		{
			tree[x].value = a[st];
			return; 
		}
		int mid = (ed - st) / 2 + st;
		bulid(st,mid,x * 2);
		bulid(mid + 1,ed,x * 2 + 1);
		tree[x].value = tree[x * 2].value + tree[x * 2 + 1].value;
	}
	
	void insert(int st,int ed,int x,ll num)
	{
		if (st <= tree[x].left && ed >= tree[x].right)
		{
			tree[x].change(num);
			return;
		}
		if (tree[x].left == tree[x].right) return;
		if (tree[x].lazy != 0)
		{
			tree[x * 2].change(tree[x].lazy);
			tree[x * 2 + 1].change(tree[x].lazy);
			tree[x].lazy = 0;
		}
		int mid = tree[x].mid();
		if (st <= mid) insert(st,ed,x * 2,num);
		if (ed > mid) insert(st,ed,x * 2 + 1,num);
		tree[x].value = tree[x * 2 + 1].value + tree[x * 2].value;
	}
	
	ll query(int st,int ed,int x)
	{
		if (tree[x].lazy != 0)
		{
			tree[2 * x].change(tree[x].lazy);
			tree[2 * x + 1].change(tree[x].lazy);
			tree[x].lazy = 0;
			tree[x].value = tree[x * 2 + 1].value + tree[x * 2].value;
		}
		if (st == tree[x].left && ed == tree[x].right) return tree[x].value;
		if (tree[x].left == tree[x].right) return 0;
		int mid = tree[x].mid();
		ll sum = 0;
		if (st <= mid)
		{
			if (ed <= mid) sum += query(st,ed,x * 2);
			else sum += query(st,mid,x * 2);
		}
		if (ed > mid)
		{
			if (st > mid) sum += query(st,ed,x * 2 + 1);
			else sum += query(mid + 1,ed,x * 2 + 1);
		}
		tree[x].value = tree[2 * x].value + tree[2 * x + 1].value;
		return sum;
	}
	
}seg;

int main()
{
	int n,q;
	cin>>n>>q;
	for (int i = 1;i<=n;i++) scanf("%d",&a[i]);
	seg.bulid(1,n,1);
	while (q--)
	{
		char c;
		getchar();
		scanf("%c",&c);
		if (c == 'Q')
		{
			int x,y;
			scanf("%d%d",&x,&y);
			ll sum = seg.query(x,y,1);
			printf("%lld\n",sum);
		}
		else if (c == 'C')
		{
			int x,y,z;
			scanf("%d%d%d",&x,&y,&z);
			seg.insert(x,y,1,z);
		}		
	}
} 

蒟蒻的线段树学习之旅,orz

posted @ 2019-05-10 18:32  Un-Defined  阅读(15)  评论(0编辑  收藏  举报  来源