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 ...
随机推荐
- TCO 2015 2D
250分题:给一段仅仅有'0','1'构成的字符串,然后给出串上平衡点的定义:在串上找到某个点(位置是p),这个点将串分成左右两部分(能够为空),左右分别计算字符的值的和,假设左边有字符是'1',那么 ...
- 2015.04.24,外语,读书笔记-《Word Power Made Easy》 12 “如何奉承朋友” SESSION 34
1.no fatigue indefatigable([indi'fætigәb(ә)l] adj. 不知疲倦的)来自faigue,in-是反义词缀:后缀-able表示able to be,因此ind ...
- Oracle 优化和性能调整
分析评价Oracle数据库性能主要有数据库吞吐量.数据库用户响应时间两项指标.数据库用户响应时间又可以分为系统服务时间和用户等待时间两项,即: 数据库用户响应时间=系统服务时间+用户等待时间 因此 ...
- jdk7与jdk8环境共存与切换
1,先安装jdk7,配置环境变量JAVA_HOME,然后安装jdk8. 2,安装jdk8后,JAVA_HOME指向未做修改,执行java -version显示还是以前的jdk7版本信息, 3,接下来我 ...
- linux 命令cp拷贝
linux复制指定目录下的全部文件到另一个目录中复制指定目录下的全部文件到另一个目录中文件及目录的复制是经常要用到的.linux下进行复制的命令为cp.假设复制源目录 为 dir1 ,目标目录为dir ...
- Java对象、Json、Xml转换工具Jackson使用
在Java项目中將一个对象转换成一段Json格式的字符串是非常常见的,能够实现这种需求的工具包也比较多,例如Gson.JSON-lib.Jackson等等.本文主要介绍Jackson的使用,Jacks ...
- ListView的Item动画
1.效果图 2.需求就是点击item歌曲时,实现一种飞入到预约按钮处的效果 3.思路:在布局文件中加入了一个条目布局,和listView的item一样,点击listView的item时,使用给条目布局 ...
- Linux下安装桌面
1. 安装之前先测试是否有桌面 2. 建立yum源文件 3. 挂载好光盘(/rhel自己创建) 4. 使用yum list 查看 ...
- iOS-Core-Animation-Advanced-Techniques/12-性能调优/性能调优.md
性能调优 代码应该运行的尽量快,而不是更快 - 理查德 在第一和第二部分,我们了解了Core Animation提供的关于绘制和动画的一些特性.Core Animation功能和性能都非常强大,但如果 ...
- 史上最低,低到尘埃,CDR邀你一起嗨购618
盼呀盼,望穿秋水~盼呀盼,何时降价~ 6.4开始,CDR X6全民狂欢618放价活动全面开启 力度之大,范围之广,时间之久,价格之低,都是前所未有的 不负众望,这个618,CDR真的做到一降到底,没有 ...