Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字
题目链接:点击打开链接
每一个点都是最大值,把一整个序列和都压缩在一个点里。
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 线段树 随意区间最大子段和 不反复数字的更多相关文章
- 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 ...
- 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 ...
- SPOJ GSS2 Can you answer these queries II ——线段树
[题目分析] 线段树,好强! 首先从左往右依次扫描,线段树维护一下f[].f[i]表示从i到当前位置的和的值. 然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值. 关于历史最值问题: 标 ...
- 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 ...
- 【BZOJ2482】[Spoj1557] Can you answer these queries II 线段树
[BZOJ2482][Spoj1557] Can you answer these queries II Description 给定n个元素的序列. 给出m个询问:求l[i]~r[i]的最大子段和( ...
- 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]| ≤ ...
- 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[ ...
- SPOJ 2916 Can you answer these queries V(线段树-分类讨论)
题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出一个数列.每次查询最大子段和Sum[i,j],其中i和j满足x1<=i<=y1,x2<=j& ...
- 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 ...
随机推荐
- 数据挖掘算法之-关联规则挖掘(Association Rule)(购物篮分析)
在各种数据挖掘算法中,关联规则挖掘算是比較重要的一种,尤其是受购物篮分析的影响,关联规则被应用到非常多实际业务中,本文对关联规则挖掘做一个小的总结. 首先,和聚类算法一样,关联规则挖掘属于无监督学习方 ...
- STL_算法_依据第n个元素排序(nth_element)
C++ Primer 学习中... 简单记录下我的学习过程 (代码为主) //全部容器适用 nth_element(b,n,e) nth_element(b,n,e,p) 对照:partition() ...
- VS2015--win32project配置的一些想法之在 Visual Studio 2015 中进行调试的同一时候分析性能
出处: https://msdn.microsoft.com/zh-cn/magazine/dn973013(en-us).aspx 很多开发商花了绝大多数时间获取应用程序才干正常发挥作用.更少的时间 ...
- 网页爬虫框架jsoup介绍
序言:在不知道jsoup框架前,因为项目需求.须要定时抓取其它站点上的内容.便想到用HttpClient方式获取指定站点的内容.这样的方法比較笨,就是通过url请求指定站点.依据指定站点返回文本解析. ...
- bzoj1790: [Ahoi2008]Rectangle 矩形藏宝地
被统考草翻回来做题不太行啊,线段树和cdq都写挂细节 这题大概就是四维偏序吧,欸n怎么到了20w,只能水70啊 但是这个好像只要有1个在里面就可以ans就可以++了耶 突然想到高中奥数老师说的,大概是 ...
- Ubuntu18.04修改Hostname
1. 设置新的hostnamesudo hostnamectl set-hostname newNameHere 2. 修改配置文件使hostname可以保存编辑这个文件: /etc/cloud/cl ...
- SQLserver中用convert函数转换日期格式(1)
SQLserver中用convert函数转换日期格式2008-01-15 15:51SQLserver中用convert函数转换日期格式 SQL Server中文版的默认的日期字段datetime格式 ...
- 关于ubuntu中文输入调用不出来的解决办法,具体如正文。
卸载了 fcitx sudo apt-get remove fcitx 重启 sudo reboot 重新安装 fcitxsudo apt-get install fcitx 安装拼音输入法sudo ...
- 判断是否是Ajax请求
Request.IsAjaxRequest()判断是否是ajax请求原理:Http协议上有个X-Requested-With:XML HttpRequest属性判断的 mvc后台通过Request可以 ...
- 关于PHP函数
从这里我开始聊一些php相关的东西了,因为视频教程里并没有讲到过多的JS,JQ,XML和AJAX,这些在后续自学之后再写一些: 有关php的基本语法数据类型什么的就不做介绍了,在PHP手册或各大学习网 ...