传送门

线段树好题

因为题目中相同的只算一次,我们可以联想到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(线段树)的更多相关文章

  1. 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 ...

  2. SPOJ GSS2 Can you answer these queries II ——线段树

    [题目分析] 线段树,好强! 首先从左往右依次扫描,线段树维护一下f[].f[i]表示从i到当前位置的和的值. 然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值. 关于历史最值问题: 标 ...

  3. 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 ...

  4. 【BZOJ2482】[Spoj1557] Can you answer these queries II 线段树

    [BZOJ2482][Spoj1557] Can you answer these queries II Description 给定n个元素的序列. 给出m个询问:求l[i]~r[i]的最大子段和( ...

  5. SP1557 GSS2 - Can you answer these queries II

    一开始看不懂题解,看懂了题解之后觉得还是挺妙的. 好多题解里都提到了HH的项链,但是我觉得关系并不大啊…… 先把所有询问离线下来按照右端点排序,按照询问的要求一个一个加入数字,怎么加入数字,我们设计一 ...

  6. Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字

    题目链接:点击打开链接 每一个点都是最大值,把一整个序列和都压缩在一个点里. 1.普通的区间求和就是维护2个值,区间和Sum和延迟标志Lazy 2.Old 是该区间里出现过最大的Sum, Oldlaz ...

  7. 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 ...

  8. SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...

  9. 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 ...

随机推荐

  1. Qt Widgets Application可执行程序发布方式

    前言 写好的Qt程序想打包发布,之前按照Qt快速入门系列教程里的方法,直接选release,构建,之后找到exe,拷贝几个dll,然而报错如图: 后来找到教程:http://tieba.baidu.c ...

  2. bzoj 1049 [HAOI2006]数字序列

    [bzoj1049][HAOI2006]数字序列 Description 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不 ...

  3. JS基础:正则表达式

    简介 正则表达式 (regular expression) 描述了一种字符串匹配的模式,可以用来检查一个字符串是否含有某种子串.将匹配的子串做替换或者从某个字符串中取出符合某个条件的子串等.在 JS ...

  4. 一练Splay之维修数列第一次

    平衡树并不是之前没写过,觉得有必要把平衡树变成考场上能敲的东西,也就是说,考一道诸如“维修数列”这样的送分题,要能拿满分. 维修数列.给定一个数列支持以下操作: 输入的第1 行包含两个数N 和M(M ...

  5. maven坐标查询

    使用maven时,一个经常用到的操作就是去 中央仓库查询相关库的坐标,但在哪里查呢? 1 http://mvnrepository.com/ 服务器是由sonatype提供的,采用的是Nexus服务器 ...

  6. POJ 3169_Layout

    大早上水一发=.= 题意: n头牛按编号顺序站成一列,给定n头牛之间的位置关系,求出第n头牛和第一头牛之间的最大距离. 分析: 差分约束系统,这题不等式关系还是挺好找的.注意因为按照顺序排列,所以有d ...

  7. [bzo1211][HNOI2004]树的计数_prufer序列

    树的计数 bzoj-1211 HNOI-2004 题目大意:题目链接. 注释:略. 想法: prufer序列有一个性质就是一个数在prufer序列中出现的次数等于这个prufer序列生成的树中它的度数 ...

  8. codevs 3164 质因数分解

    3164 质因数分解  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description (多数据)给出t个数,求出它的质因子个 ...

  9. 所有的异常都要使用try catch 语句捕获?

    在开发应用程序过程中必须检测代码可能发生的错误并进行正确的处理,这个在理想的情况下,应用程序中的每行 代码都按照预想的执行,要用到的每种资源总是可以利用,但是在实际的开发过程中,写代码难免会出错,或是 ...

  10. Linux命令输出头(标题)、输出结果排序技巧

    原文:http://blog.csdn.net/hongweigg/article/details/65446007 ----------------------------------------- ...