题目链接:点击打开链接

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

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. Nginx 做系统的前端反向proxy

    Nginx是一款很优秀的基于event的webserver.吞吐量大.占用资源少,只是文档就很让人郁闷了,免费的Nginx和收费的Nginx+的文档共用一份,配置完之后才发现免费的Nginx启动某些命 ...

  2. Autodesk 举办的 Revit 2015 二次开发速成( 1.5 天),教室培训, 地点武汉

    2014年8月26日9:00 – 17:00 2014年8月27日9:00 – 12:00 培训地点: Ø 湖北工业大学 实训楼605教室 Ø 地址:武汉市武昌区南湖李家墩一村一号 Ø 交通路线说明: ...

  3. svn 服务器的搭建

     SVN服务器运行模式:模式1:svn服务器单独运行  监听: 3690端口    访问: svn://IP模式2: svn 服务器+ apache   : 80 端口  访问: http://IP  ...

  4. C# Parse and TryParse 方法详解

    工作中遇到的常用方法: Parse and TryParse TryParse 方法类似于 Parse 方法,不同之处在于 TryParse 方法在转换失败时不引发异常 /// <summary ...

  5. [C#] 隐式类型var —— 示例解析

    从 Visual C# 3.0 开始,在方法范围中声明的变量可以具有隐式类型var.隐式类型可以替代任何类型,它的具体类型由编译器根据上下文推断而出. 下面就让我来总结下隐式类型的一些特点: 1.va ...

  6. Centos7 minimal 系列之rabbitmq安装(八)

    一.安装Erlang 由于RabbitMQ依赖Erlang, 所以需要先安装Erlang. 这种方法网站访问不了 wget https://packages.erlang-solutions.com/ ...

  7. 2017.7.15清北夏令营精英班Day1解题报告

    成绩: 预计分数:20+10+40 实际分数:100+10+40. 一百三十多人的比赛全场rand7还水了个鼠标+键盘 unbelievable! 考试题目链接: https://www.luogu. ...

  8. javascript动画函数封装(升级版)

    //把 任意对象 的 任意数值属性 改变为 任意的目标值 function animate(obj, json, fn) { clearInterval(obj.timer); obj.timer = ...

  9. js中,实现对键盘按键的监听:

    <script> function keyUp(e) { var currKey=0,e=e||event; currKey=e.keyCode||e.which||e.charCode; ...

  10. UNP学习笔记3——基本UDP套接字编程

    1 概述 TCP和UDP网络编程存在一些本质的差异,主要是由于传输层的差别:UDP是无连接的不可靠的数据报协议,而TCP是面向连接的字节流协议. 下图是典型的UDP客户端和服务器之间的通信流程.客户不 ...