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

Spoj 1557 Can you answer these queries II 线段树 任意区间最大子段和 不重复数字

时间:2014-08-31 14:33:31      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:http   os   io   ar   for   sp   amp   on   line   

题目链接:点击打开链接

每个点都是最大值,把一整个序列和都压缩在一个点里。



#include <vector>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
using namespace std;
#define N 100005
#define Lson(x) (x<<1)
#define Rson(x) (x<<1|1)
#define L(x) tree[x].l
#define R(x) tree[x].r
#define Old(x) tree[x].old
#define Sum(x) tree[x].sum
#define Lazy(x) tree[x].lazy
#define Olazy(x) tree[x].oldlazy
inline int Mid(int l, int r){return (l+r)>>1;}
struct Subtree{
	int l, r;
	int old, oldlazy, sum, lazy;
}tree[N<<2];
void push_down(int id){
	if(L(id) == R(id)) return ;
	if(Lazy(id) || Olazy(id)){
		Olazy(Lson(id)) = max(Olazy(Lson(id)), Lazy(Lson(id)) + Olazy(id));
		Old(Lson(id)) = max(Old(Lson(id)), Sum(Lson(id)) + Olazy(id));
		Lazy(Lson(id)) += Lazy(id); Sum(Lson(id)) += Lazy(id);

		Olazy(Rson(id)) = max(Olazy(Rson(id)), Lazy(Rson(id)) + Olazy(id));
		Old(Rson(id)) = max(Old(Rson(id)), Sum(Rson(id)) + Olazy(id));
		Lazy(Rson(id)) += Lazy(id); Sum(Rson(id)) += Lazy(id);
		Lazy(id) = Olazy(id) = 0;
	}
}
void push_up(int id){
	if(L(id) == R(id)) return ;
	Old(id) = max(Old(Lson(id)), Old(Rson(id)));
	Sum(id) = max(Sum(Lson(id)), Sum(Rson(id)));
}
void build(int l, int r, int id){
	L(id) = l; R(id) = r;
	Sum(id) = Old(id) = Lazy(id) = Olazy(id) = 0;
	if(l == r) return ;
	int mid = Mid(l, r);
	build(l, mid, Lson(id)); build(mid+1, r, Rson(id));
}
void updata(int l, int r, int val, int id){
	push_down(id);
	if(l == L(id) && R(id) == r) {
		Sum(id) += val;
		Lazy(id) += val;
		Olazy(id) = max(Olazy(id), Lazy(id));
		Old(id) = max(Old(id), Sum(id));
		return ;
	}
	int mid = Mid(L(id), R(id));
	if(mid < l)
		updata(l, r, val, Rson(id));
	else if(r <= mid)
		updata(l, r, val, Lson(id));
	else {
		updata(l, mid, val, Lson(id));
		updata(mid+1, r, val, Rson(id));
	}
	push_up(id);
}
int Query(int l, int r, int id){
	push_down(id);
	if(l == L(id) && R(id) == r) return Old(id);
	int ans , mid = Mid(L(id), R(id));
	if(mid < l)
		ans = Query(l, r, Rson(id));
	else if(r <= mid)
		ans = Query(l, r, Lson(id));
	else 
		ans = max(Query(l, mid, Lson(id)), Query(mid+1, r, Rson(id)));
	push_up(id);
	return ans;
}
int a[N], n, las[N<<1];
struct node{
	int l, r, num, ans;
}query[N];
bool cmp1(node a, node b){return a.r < b.r;}
bool cmp2(node a, node b){return a.num < b.num;}
void solve(){
	int i, q;
	for(i = 1; i <= n; i++)scanf("%d",&a[i]);
	build(1, n, 1);
	scanf("%d",&q);
	for(i = 1; i <= q; i++)scanf("%d %d",&query[i].l, &query[i].r), query[i].num = i;
	sort(query+1, query+q+1, cmp1);
	int top = 1;
	memset(las, 0, sizeof las);
	for(i = 1; i <= n && top <= q; i++){
		updata(las[a[i]+N]+1, i, a[i], 1);
		las[a[i]+N] = i;
		while(query[top].r == i && top <= q){
			query[top].ans = Query(query[top].l, query[top].r, 1);
			top++;
		}
	}
	sort(query+1, query+q+1, cmp2);
	for(i = 1; i <= q; i++)printf("%d\n", query[i].ans);
}
int main(){
	while(~scanf("%d",&n))
		solve();	
	return 0;
}


Spoj 1557 Can you answer these queries II 线段树 任意区间最大子段和 不重复数字

标签:http   os   io   ar   for   sp   amp   on   line   

原文地址:http://blog.csdn.net/qq574857122/article/details/38959809

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