题目链接:点击打开链接

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

1、普通的区间求和就是维护2个值,区间和Sum和延迟标志Lazy

2、Old 是该区间里出现过最大的Sum, Oldlazy 是对于给下一层的子区间的标志,添加多少是能给子区间添加的值最大的(用来维护Old)

显然对于Old 。要么维持原样,要么更新为稍新的值:即 Sum(id) + Oldlazy

而对于Oldlazy, 要么维持原样,要么变成最新的延迟标记:即 Lazy(id) + Oldlazy

上2行的Oldlazy都是指对这个tree[id]有效的,即他们父节点的Oldlazy - > Oldlazy( id / 2 )

#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 线段树 随意区间最大子段和 不反复数字的更多相关文章

  1. SPOJ 1557. Can you answer these queries II 线段树

    Can you answer these queries II Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://www.spoj.com/pr ...

  2. bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树

    2482: [Spoj1557] Can you answer these queries II Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 145 ...

  3. SPOJ GSS2 Can you answer these queries II ——线段树

    [题目分析] 线段树,好强! 首先从左往右依次扫描,线段树维护一下f[].f[i]表示从i到当前位置的和的值. 然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值. 关于历史最值问题: 标 ...

  4. SPOJ GSS3 Can you answer these queries III[线段树]

    SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...

  5. 【BZOJ2482】[Spoj1557] Can you answer these queries II 线段树

    [BZOJ2482][Spoj1557] Can you answer these queries II Description 给定n个元素的序列. 给出m个询问:求l[i]~r[i]的最大子段和( ...

  6. SPOJ GSS1 - Can you answer these queries I(线段树维护GSS)

    Can you answer these queries I SPOJ - GSS1 You are given a sequence A[1], A[2], -, A[N] . ( |A[i]| ≤ ...

  7. GSS5 spoj 2916. Can you answer these queries V 线段树

    gss5 Can you answer these queries V 给出数列a1...an,询问时给出: Query(x1,y1,x2,y2) = Max { A[i]+A[i+1]+...+A[ ...

  8. SPOJ 2916 Can you answer these queries V(线段树-分类讨论)

    题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出一个数列.每次查询最大子段和Sum[i,j],其中i和j满足x1<=i<=y1,x2<=j& ...

  9. SPOJ - GSS1-Can you answer these queries I 线段树维护区间连续和最大值

    SPOJ - GSS1:https://vjudge.net/problem/SPOJ-GSS1 参考:http://www.cnblogs.com/shanyr/p/5710152.html?utm ...

随机推荐

  1. 远程视频监控之驱动篇(LED)

    转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/38515205 之前一直在考虑该不该写这篇,由于我之前在博客里有写过LED的驱动 ...

  2. Highcharts数据表示(2)

    Highcharts数据表示(2) 数据节点是图表中最小的元素.每一个数据节点都是一个数据单元. 它确定了图表中一个图形元素的各种信息.一个数据节点通常包含下面三类信息: 1.坐标位置信息 因为Hig ...

  3. unity3d Pathfinding插件使用

    Overview The central script of the A* Pathfinding Project is the script 'astarpath.cs', it acts as a ...

  4. #定位系统性能瓶颈# perf

    perf是一个基于Linux 2.6+的调优工具,在liunx性能測量抽象出一套适应于各种不同CPU硬件的通用測量方法,其数据来源于比較新的linux内核提供的 perf_event 接口 系统事件: ...

  5. UVA 11728 - Alternate Task 数学

    Little Hasan loves to play number games with his friends. One day they were playing a game whereone ...

  6. oracle 11gR2 如何修改 private ip

    1.1    修改 private ip1.1.1  确保crs集群是打开的可以用olsnodes –s 检查集群的状态./olsnodes -sP570a ActiveP570b Active1.1 ...

  7. Spark RDD概念学习系列之如何创建Pair RDD

    不多说,直接上干货! 创建Pair RDD Python语言 pairs = lines.map(lambda x: (x.split(], x))  scala语言 val pairs = line ...

  8. python课程设计笔记(一)开发环境配置

    今天开始学python,一个月后交成果?还是希望自己不要浮躁,认真地去学,有所付出也不期望太大回报. 现在还是一脸懵逼的状态,看着教程一点点来吧= = 毕竟我是最棒的最发光的阳光彩虹小白马! 1. 去 ...

  9. mysql 导入数据库 命令操作

    window下 1.导出整个数据库 mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump -u dbuser -p dbname > dbname.sql ...

  10. vue2.0中关于active-class

    一.首先,active-class是什么, active-class是vue-router模块的router-link组件中的属性,用来做选中样式的切换: 相关可查阅文档:https://router ...