SP1557 GSS2 - Can you answer these queries II(线段树)
线段树好题
因为题目中相同的只算一次,我们可以联想到HH的项链,于是考虑离线的做法
先把所有的询问按$r$排序,然后每一次不断将$a[r]$加入线段树
线段树上维护四个值,$sum,hix,sumtag,hixtag$,分别代表当前节点的值,节点历史上的最大值,当前的增加标记,历史上最大的增加标记
然后pushdown的过程可以看代码,还是比较清楚的
考虑怎么添加元素,设序列中上一个与$i$相等的数的位置是$Pre[i]$,那么就把区间$[Pre[i],i]$加$a[i]$即可
查询的话只要查$[l,r]$的$hix$即可
除了pushdown有点烦其他都还好
//minamoto
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ls (p<<1)
#define rs (p<<1|1)
#define ll long long
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
ll read(){
#define num ch-'0'
char ch;bool flag=;ll res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
void print(ll x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e5+;
struct node{
ll sum,hix,stag,htag;
node(){sum=hix=stag=htag=;}
inline node operator +(node b){
node res;
res.sum=max(sum,b.sum),res.hix=max(hix,b.hix);
return res;
}
}b[N<<];
struct Q{
int l,r,id;
inline bool operator <(const Q b)const
{return r<b.r;}
}q[N];
int n,m,cur[N*],Pre[N],ql,qr;ll a[N],ans[N],k;
inline void upd(int p){b[p]=b[ls]+b[rs];}
void pd(int p){
b[ls].hix=max(b[ls].hix,b[ls].sum+b[p].htag);
b[rs].hix=max(b[rs].hix,b[rs].sum+b[p].htag);
b[ls].sum+=b[p].stag,b[rs].sum+=b[p].stag;
b[ls].htag=max(b[ls].htag,b[ls].stag+b[p].htag);
b[rs].htag=max(b[rs].htag,b[rs].stag+b[p].htag);
b[ls].stag+=b[p].stag,b[rs].stag+=b[p].stag;
b[p].stag=b[p].htag=;
}
void update(int p,int l,int r){
if(ql<=l&&qr>=r){
b[p].sum+=k,cmax(b[p].hix,b[p].sum);
b[p].stag+=k,cmax(b[p].htag,b[p].stag);
return;
}
pd(p);int mid=(l+r)>>;
if(ql<=mid) update(ls,l,mid);
if(qr>mid) update(rs,mid+,r);
upd(p);
}
node query(int p,int l,int r){
if(ql<=l&&qr>=r) return b[p];
pd(p);int mid=(l+r)>>;
if(ql>mid) return query(rs,mid+,r);
else if(qr<=mid) return query(ls,l,mid);
else return query(ls,l,mid)+query(rs,mid+,r);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read();
for(int i=;i<=n;++i)
a[i]=read(),Pre[i]=cur[a[i]+(int)1e5],cur[a[i]+(int)1e5]=i;
m=read();
for(int i=;i<=m;++i)
q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+,q++m);
for(int i=,j=;i<=n&&j<=m;++i){
ql=Pre[i]+,qr=i,k=a[i];update(,,n);
for(;j<=m&&q[j].r<=i;++j){
ql=q[j].l,qr=q[j].r;
ans[q[j].id]=query(,,n).hix;
}
}
for(int i=;i<=m;++i) print(ans[i]);
return Ot(),;
}
SP1557 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 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]的最大子段和( ...
- SP1557 GSS2 - Can you answer these queries II
一开始看不懂题解,看懂了题解之后觉得还是挺妙的. 好多题解里都提到了HH的项链,但是我觉得关系并不大啊…… 先把所有询问离线下来按照右端点排序,按照询问的要求一个一个加入数字,怎么加入数字,我们设计一 ...
- 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 ...
- SPOJ GSS1_Can you answer these queries I(线段树区间合并)
SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...
- spoj gss2 : Can you answer these queries II 离线&&线段树
1557. Can you answer these queries II Problem code: GSS2 Being a completist and a simplist, kid Yang ...
随机推荐
- HDU 4478 Where is King
题目大意: 一个王可以向周围8个方格走,如果都不通留在原地,t秒后,他可能存在的位置数 这题数据量过大,我们需要通过奇偶性判断,如果t = 0可以到达,说明 t=2,4,6....都可以到达 所以我这 ...
- Count the Colors-ZOJ1610(线段树区间求)
Painting some colored segments on a line, some previously painted segments may be covered by some th ...
- MySQL查询去重语句
1.distinct select count(distinct CName) from Course select count(CName) from (select distinct CName ...
- Spring Boot实现多个数据源教程收集(待实践)
先收集,后续实践. http://blog.csdn.net/catoop/article/details/50575038 http://blog.csdn.net/neosmith/article ...
- JSP的会话(Session)跟踪
以下内容引用自http://wiki.jikexueyuan.com/project/jsp/session-tracking.html: 会话(Session) HTTP是一个“无状态”协议,这意味 ...
- CE310A
http://v.ku6.com/show/tvWNTLZTVWuGVPE5ZMSUyQ...html
- C#代码读写XML
<1> 创建XML文档 using System; using System.Collections.Generic; using System.Linq; using System.Te ...
- Python学习系列之内置函数
数学相关 abs(a):求取绝对值 max(list):求取list最大值 min(list):求取list最小值 sum(list):求取list元素的和 sorted(list):排序,返回排序后 ...
- [AngularJS] ocLazyLoad -- Lazy loaded module should contain all the dependencies code
Recentlly works with AngularJS + ocLazyLoad, our project have break down into multi small modules. F ...
- [Java Sprint] Spring XML Configuration : Setter Injection Demo
In CustomerServiceImpl.java, we hardcoded 'HibernateCustomerRepositoryImpl' package com.pluralsight. ...