码迷,mamicode.com
首页 > 其他好文 > 详细

Poj(3468)——A Simple Problem with Integers(线段树)

时间:2015-05-30 16:47:43      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:acm   线段树   

A Simple Problem with Integers
Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 72424   Accepted: 22343
Case Time Limit: 2000MS

Description

You have N integers, A1A2, ... , 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 A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+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

这道题的大致题目意思是:

首先给你两个整数N,Q;N代表的是你有几个数,然后Q代表的是有几个操作:

然后只有两种操作类型,"C a b c"代表的意思是:给A[a]到A[b]的数都加上一个数c。 "Q a b”的意思是让你求下标为a到b的和。

线段树裸题,但是是第一次做,所以还是写写吧,而且网上线段树模板鱼龙混杂,我也是费了好大力气才找到一个适合我的模板的。

在此附上链接:http://www.tuicool.com/articles/BVVfi2E

如果不懂线段树的可以先去学习一下上面那个人写的内容然后这道题我想就很简单了吧。

Source Code

Problem: 3468		User: hclmaster
Memory: 8352K		Time: 2110MS
Language: C++		Result: Accepted
Source Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define maxn 111111
typedef long long ll;
ll ans=0;
ll N,Q;
struct node{
	ll l,r;
	ll add,sum;
}tree[maxn*4];
void pushdown(ll v){
	ll temp=v*2;
	tree[temp].add+=tree[v].add;
	tree[temp+1].add+=tree[v].add;
	tree[temp].sum+=tree[v].add*(tree[temp].r-tree[temp].l+1);
	tree[temp+1].sum+=tree[v].add*(tree[temp+1].r-tree[temp+1].l+1);
	tree[v].add=0;
}
void pushup(ll v){
	ll temp=2*v;
	tree[v].sum=tree[temp].sum+tree[temp+1].sum;
}
void build(int l,int r,int v){
	tree[v].l=l;
	tree[v].r=r;
	tree[v].add=0;
	if(l==r){
		scanf("%lld",&tree[v].sum);
		return ;
	}
	int temp=v<<1;
	int mid=(l+r)>>1;
	build(l,mid,temp);
	build(mid+1,r,temp+1);
	pushup(v);
}
void query(ll l,ll r,ll v){
	if(r<tree[v].l||l>tree[v].r) return ;
	if(l<=tree[v].l&&tree[v].r<=r){
		ans+=tree[v].sum;
		return;
	}
	if(tree[v].add){
		pushdown(v);
	}
	ll temp=v<<1;
	ll mid=(tree[v].l+tree[v].r)>>1;
	if(r<=mid) query(l,r,temp);
	else if(l>mid) query(l,r,temp+1);
	else{
		query(l,mid,temp);
		query(mid+1,r,temp+1);
	}
}
void update(ll l,ll r,ll v,ll x){
	if(r<tree[v].l||tree[v].r<l) return ;
	if(l<=tree[v].l&&tree[v].r<=r){
		tree[v].add+=x;
		tree[v].sum+=x*(tree[v].r-tree[v].l+1);
		return ;
	}
	if(tree[v].add){
		pushdown(v);
	}
	ll temp=v<<1;
	update(l,r,temp,x);
	update(l,r,temp+1,x);
	pushup(v);
}
int main(){
	while(~scanf("%d%d",&N,&Q)){
		build(1,N,1);
		char ss[6];
		while(Q--){
			scanf("%s",ss);
			if(ss[0]=='Q'){
				ll l,r;
				scanf("%lld%lld",&l,&r);
				ans=0;
				query(l,r,1);
				printf("%lld\n",ans);
			}
			else{
				ll l,r,x;
				scanf("%lld%lld%lld",&l,&r,&x);
				update(l,r,1,x);	
			}
		}
	}
}

没有什么新的东西是刚开始就能够得心应手的,所以慢慢的进步吧,加油,hades!


Poj(3468)——A Simple Problem with Integers(线段树)

标签:acm   线段树   

原文地址:http://blog.csdn.net/acmer_hades/article/details/46274825

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!