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 ...
随机推荐
- [luoguP1077] 摆花(DP)
传送门 f[i][j] 表示前 i 种花,摆 j 盆的方案数 j f[i][j] = Σ f[i - 1][j] k=max(0, j - a[i]) 博客园这个公式该怎么打啊.. ——代码( ...
- hdu 5073 推公式相邻质心转换
#include<stdio.h> #include<stdlib.h> #include<string.h> #define N 51000 int cmp(co ...
- hdu3440 House Man 【差分约束系统】
House Man Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- Git Cheat Sheet 中文版
Git Cheat Sheet 中文版 索引 配置 配置文件 创建 本地修改 搜索 提交历史 分支与标签 更新与发布 合并与重置 撤销 Git Flow 配置 列出当前配置: $ git config ...
- <项目><day11>查看用户浏览过的商品
<项目>查看用户浏览过的商品 1.创建一个entity包储存实体对象 1.1创建一个Product的类存储实体对象 对象具有以下属性,并添加set和get方法,含参和不含参的构造方法,to ...
- Session&Cookie 的介绍和使用
Session介绍与使用 1.Session基本介绍 Session:在计算机中,尤其是在网络应用中,称为“会话控制”.Session 对象存储特定用户会话所需的属性及配置信息.这样,当用户在应用程序 ...
- openstack setup demo Image service
Image service (glance)是openstack中管理vm image的service.本文包含以下内容: overview install overview glance包含以下部分 ...
- Mybatis 最强大的动态sql <where>标签
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHER ...
- S5P4418裸机开发系列教程--源代码下载
S5P4418裸机系列教程之stdio S5P4418裸机系列教程之shell命令行 S5P4418裸机系列教程之串口回显 S5P4418裸机系列教程之复位測试 S5P4418裸机系列教程之led跑马 ...
- Class 与 new的配合使用
class Type{ // 定义新的类型Type /// ...... }; Type a; Type b; // 像int a; int b;那样使用, 定义a和b为Type类型的变量 in ...