SPOJ 1557 GSS2 - Can you answer these queries II (线段树+维护历史最值)
都说这题是 GSS 系列中最难的,今天做了一下,名副其实
首先你可以想到各种各样的在线乱搞想法,线段树,主席树,平衡树,等等,但发现都不太可行。
注意到题目也没有说强制在线,因此可以想到离线地去解决这道题。
我们把询问按照右端点从小到大排序。假设当前询问的右端点为 \(i\)。
定义 \(s_j\) 为 \([j,i]\) 中不重复数字的和。我们建一棵线段树维护 \(s_j\) 的最大值。
这样修改起来就比较自然了,当右端点从 \(i-1\) 变到 \(i\) 的时候,记 \(a_i\) 上一次出现的位置为 \(k\),那么这个 \(a_i\) 只会对 \(s_{k+1},s_{k+2},\dots,s_i\) 产生贡献,也就是说我们在线段树上 \([k+1,i]\) 位置上的数 \(+a_i\)。
询问也比较容易。询问 \((l,i)\) 的答案就是 \(s_l,s_{l+1},\dots,s_i\) 的历史最大值。
这样原题就转化为一道看起来比较可做的 DS 了,要你维护一个序列,支持:
- 区间加
- 区间历史最大值
之前写过一道类似的题题号什么我忘了,可现在忘了怎么做了/kk,只好看题解再推一遍。
线段树区间维护四个东西 \(mx,hmx,lz,hlz\) 表示最大值,历史最大值,区间加标记,历史最大区间加标记(历史出现过的懒标记的最大值)。
上推操作就不用说了吧,直接对 \(mx,hmx\) 取 \(\max\)。。。。。。
区间加上一个值 \(v\),那么最大值肯定也会加上 \(v\),历史最大值就和当前最大值取 \(\max\),懒标记也同理。
最复杂的就是如何下传标记。
例如我们现在有一段操作序列 \(+1-3+4-2-1+5-2\),那么此时懒标记为 \(+2\),历史最大懒标记为 \(+4\)(\(+1-3+4-2-1+4\))。
然后它的儿子当前最大值为 \(2\),历史最大值为 \(3\),当前懒标记为 \(-1\),历史最大懒标记为 \(+1\)。
那么:
- \(mx\) 显然直接加上父亲的懒标记即可,\(2+1-3+4-2-1+5-2=2+2=4\)。
- \(hmx\) 拿当前最大值 \(2\) 加上历史最大懒标记 \(+4\)(\(2+1-3-4-2-1+5=6\)),与原来历史最大值 \(3\) 比较。
- \(lz\) 也是直接加上父亲的 \(lz\) 即可,\(-1+2=+1\)
- \(hlz\) 也拿当前最大懒标记加上历史最大懒标记 \(+4\)(\(-1+1-3-4-2-1+5=+3\)),与原来历史最大懒标记 \(+1\) 比较。
最后,重中之重,下放懒标记的顺序一定要注意。
/*
Contest: -
Problem: SP1557
Author: tzc_wk
Time: 2020.8.8
*/
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a) a.begin(),a.end()
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1 y1010101010101
#define y0 y0101010101010
#define int long long
typedef pair<int,int> pii;
inline int read(){
int x=0,neg=1;char c=getchar();
while(!isdigit(c)){
if(c=='-') neg=-1;
c=getchar();
}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*neg;
}
int n=read(),m,a[100005],ans[100005];
struct _query{
int l,r,id;
friend bool operator <(_query a,_query b){
return a.r<b.r;
}
} q[100005];
struct node{
int l,r,mx,hmx,lz,hlz;
} s[100005<<2];
inline void pushup(int k){
s[k].mx=max(s[k<<1].mx,s[k<<1|1].mx);
s[k].hmx=max(s[k<<1].hmx,s[k<<1|1].hmx);
}
inline void build(int k,int l,int r){
s[k].l=l;s[k].r=r;
if(l==r) return;
int mid=(l+r)>>1;
build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}
inline void pushdown(int k){
s[k<<1].hmx=max(s[k<<1].hmx,s[k<<1].mx+s[k].hlz);
s[k<<1|1].hmx=max(s[k<<1|1].hmx,s[k<<1|1].mx+s[k].hlz);
s[k<<1].mx+=s[k].lz;
s[k<<1|1].mx+=s[k].lz;
s[k<<1].hlz=max(s[k<<1].hlz,s[k<<1].lz+s[k].hlz);
s[k<<1|1].hlz=max(s[k<<1|1].hlz,s[k<<1|1].lz+s[k].hlz);
s[k<<1].lz=s[k<<1].lz+s[k].lz;
s[k<<1|1].lz=s[k<<1|1].lz+s[k].lz;
s[k].lz=s[k].hlz=0;
}
inline void add(int k,int l,int r,int x){
if(l<=s[k].l&&s[k].r<=r){
s[k].mx+=x;s[k].hmx=max(s[k].hmx,s[k].mx);
s[k].lz+=x;s[k].hlz=max(s[k].hlz,s[k].lz);
return;
}
pushdown(k);
int mid=(s[k].l+s[k].r)>>1;
if(r<=mid) add(k<<1,l,r,x);
else if(l>mid) add(k<<1|1,l,r,x);
else add(k<<1,l,mid,x),add(k<<1|1,mid+1,r,x);
pushup(k);
}
inline int query(int k,int l,int r){
if(l<=s[k].l&&s[k].r<=r){
return s[k].hmx;
}
pushdown(k);
int mid=(s[k].l+s[k].r)>>1;
if(r<=mid) return query(k<<1,l,r);
else if(l>mid) return query(k<<1|1,l,r);
else return max(query(k<<1,l,mid),query(k<<1|1,mid+1,r));
}
map<int,int> mp;
signed main(){
fz(i,1,n) a[i]=read();
m=read();fz(i,1,m) q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+1,q+m+1);
build(1,1,n);
int cur=1;
fz(i,1,n){
add(1,mp[a[i]]+1,i,a[i]);mp[a[i]]=i;
while(cur<=m&&q[cur].r<=i){
ans[q[cur].id]=query(1,q[cur].l,q[cur].r);cur++;
}
}
fz(i,1,m) printf("%lld\n",ans[i]);
return 0;
}
SPOJ 1557 GSS2 - Can you answer these queries II (线段树+维护历史最值)的更多相关文章
- 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 1557 GSS3 - Can you answer these queries III 线段树
题目链接 给出n个数, 2种操作, 一种是将第x个数改为y, 第二种是询问区间[x,y]内的最大连续子区间. 开4个数组, 一个是区间和, 一个是区间最大值, 一个是后缀的最大值, 一个是前缀的最大值 ...
- SPOJ GSS2 Can you answer these queries II ——线段树
[题目分析] 线段树,好强! 首先从左往右依次扫描,线段树维护一下f[].f[i]表示从i到当前位置的和的值. 然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值. 关于历史最值问题: 标 ...
- 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 ...
- 【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]| ≤ ...
- 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 ...
- Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字
题目链接:点击打开链接 每一个点都是最大值,把一整个序列和都压缩在一个点里. 1.普通的区间求和就是维护2个值,区间和Sum和延迟标志Lazy 2.Old 是该区间里出现过最大的Sum, Oldlaz ...
- SPOJ GSS2 - Can you answer these queries II(线段树 区间修改+区间查询)(后缀和)
GSS2 - Can you answer these queries II #tree Being a completist and a simplist, kid Yang Zhe cannot ...
随机推荐
- 改善深层神经网络-week1编程题(GradientChecking)
1. Gradient Checking 你被要求搭建一个Deep Learning model来检测欺诈,每当有人付款,你想知道是否该支付可能是欺诈,例如该用户的账户可能已经被黑客掉. 但是,反向传 ...
- 解决git clone慢问题
解决git clone慢 关于Git克隆或是上传代码龟速的问题真是让人很恼火,这里对于网上的两种解决方案进行摘录. 利用码云克隆github项目 亲测有效 进入码云,新建一个仓库: 在创建的最后选择导 ...
- 计算机网络之应用层概述(C/S模型与p2p模型)
文章转自:https://blog.csdn.net/weixin_43914604/article/details/105582318 学习课程:<2019王道考研计算机网络> 学习目的 ...
- Python ImportError: cannot import name ABC
Python 3.5.2 测试可以运行 import sys from abc import ABC,abstractmethod class MyBase(ABC): @abstractmethod ...
- ICPC Mid-Central USA Region 2019 题解
队友牛逼!带我超神!蒟蒻的我还是一点一点的整理题吧... Dragon Ball I 这个题算是比较裸的题目吧....学过图论的大概都知道应该怎么做.题目要求找到七个龙珠的最小距离.很明显就是7个龙珠 ...
- 最后的OI(HAOI2020游记)
马上就省选了,怎么不得写点什么?要不然到最后或许就真的落得个白茫茫大地真干净的局面. 其实也不知道该说啥?我这一路走来,感觉挺赚的. 每一个OIer背后都有一个故事,所以,我有故事,你有酒吗? 依稀记 ...
- 第11课 OpenGL 飘动的旗帜
飘动的旗帜: 这一课从第六课的代码开始,创建一个飘动的旗帜.我相信在这课结束的时候,你可以掌握纹理映射和混合操作. 大家好!对那些想知道我在这里作了些什么的朋友,您可以先按文章的末尾所列出的链接,下载 ...
- spring-cloud-square源码速读(spring-cloud-square-okhttp篇)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 中文NER的那些事儿4. 数据增强在NER的尝试
这一章我们不聊模型来聊聊数据,解决实际问题时90%的时间其实都是在和数据作斗争,于是无标注,弱标注,少标注,半标注对应的各类解决方案可谓是百花齐放.在第二章我们也尝试通过多目标对抗学习的方式引入额外的 ...
- echarts 让轴自适应数据为小数整数
echarts 让轴自适应数据为小数整数,以解决y轴数值重复的问题 工作中突然遇到这个问题 试了一下用formatter自适应 ok 在yAxis中提阿尼按键属性 axisLabel 1 axis ...