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 ...
随机推荐
- 587. Erect the Fence
Problem statement: There are some trees, where each tree is represented by (x,y) coordinate in a two ...
- android源码编译时拷贝替换指定文件
由于要做版本定制,某些版本的资源文件等(例如style.xml)需要不同的配置,但是android的编译开关无法在xml里使用,于是想到了编译时根据不同的编译开关编译不同的文件,如下: 1.建立A.x ...
- Jquery判断某个字符串是否在数组中
使用$.inArray方法判断,如果存在则返回0,不存在返回-1,结果如下: 另外也可以将数组转为字符串,并使用正则表达式处理
- scp远程文件传输
第一次.提示下载公钥 [root@rhel5 ~]# scp install.log root@192.168.124.129:/tmp The authenticity of host '192.1 ...
- 远程调试 Android 设备使用入门(谷歌翻译版)
移动前端调试方案(Android + Chrome 实现远程调试) 目录 要求 第 1 步:发现您的 Android 设备 第 2 步:从您的开发计算机调试 Android 设备上的内容. 更多操作: ...
- Kerberos认证浅析
1 引言 在希腊神话中Kerberos是守护地狱之门的一条凶猛的三头神犬,而我们在本文中所要介绍的Kerberos认证协议是由美国麻省理工学院(MIT)首先提出并实现的,是该校雅典娜计划的一部分.这个 ...
- Systemtap工具查看系统资源使用
http://www.xbwolf.com/507 http://blog.csdn.net/kafeiflynn/article/details/6429976 安装步骤yum install sy ...
- pycharm内存不足时如何修改设置?
Help->Find Action->(type "VM Options")->(Click)"Edit Custom VM Options" ...
- (linux shell)第一章--小试牛刀(下)
文章来源: (linux shell)第一章--小试牛刀(下) 1.6 数组和关联数组 1.6.1 预备知识 Bash同一时候支持普通数组和关联数组.普通数组仅仅能使用整数作为数组索引,而关联数组能够 ...
- SDUT--找朋友(BFS&&DFS)
找朋友 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描写叙述 X,作为户外运动的忠实爱好者,总是不想呆在家里.如今,他想把死宅Y从家 ...