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 MB
Submit: 145 Solved: 76
[Submit][Status][Discuss]
Description
给定n个元素的序列。
给出m个询问:求l[i]~r[i]的最大子段和(可选空子段)。
这个最大子段和有点特殊:一个数字在一段中出现了两次只算一次。
比如:1,2,3,2,2,2出现了3次,但只算一次,于是这个序列的和是1+2+3=6。
Input
第一行一个数n。
第二行n个数,为给定的序列,这些数的绝对值小于等于100000。
第三行一个数m。
接下来m行,每行两个数,l[i],r[i]。
Output
M行,每行一个数,为每个询问的答案。
Sample Input
4 -2 -2 3 -1 -4 2 2 -6
3
1 2
1 5
4 9
Sample Output
5
3
HINT
【数据说明】
30%:1 <= n, m <= 100
100%:1 <= n, m <= 100000
一年前抄标程把spoj的gss2做了,一年后重新做了一遍,仍然把我恶心的。。。。【话说这道题没卡longlong很不爽】
还是一步一步想吧,首先是离线,转成线段树的区间加,询问区间最大值的历史最大值。
这东西怎么搞呢?
我们先不考虑下放标记的问题,单考虑一个结点。
记录plus[]表示从上次清除tag到现在,已经有多少“加”操作下降到当前点。
记录hplus[]表示从上次清除tag到现在,历史加操作“峰值”与plus的差值。
在不考虑下放的情况下每次加v操作及plus+=v,hplus=max(0,hplus-v);
当然作为线段树,我们还要记录maxv表示当前区间的答案,及区间历史最大值。
然后再考虑标记下方问题。
在调试中发现单纯maxv很难维护,需要在加一个中间变量,视为nmaxv,及当前最大值。
转移什么的知道变量含义就可以参考代码了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<assert.h>
using namespace std;
#define MAXN 110000
#define MAXQ MAXN
#define MAXT MAXN*5
#define lch (now<<1)
#define rch (now<<1^1)
#define smid ((l+r)>>1)
#define INF 0x3f3f3f3f
typedef long long qword;
struct sgt_node
{
qword plus,maxv;
qword hplus;
qword nmaxv;
}sgt[MAXT];
void make_plus(int now,qword v)
{
sgt[now].hplus-=v;
sgt[now].plus+=v;
sgt[now].hplus=max(sgt[now].hplus,0ll);
sgt[now].nmaxv+=v;
sgt[now].maxv=max(sgt[now].maxv,sgt[now].nmaxv+sgt[now].hplus);
}
void down(int now)
{
make_plus(lch,sgt[now].plus+sgt[now].hplus);
make_plus(lch,-sgt[now].hplus);
make_plus(rch,sgt[now].plus+sgt[now].hplus);
make_plus(rch,-sgt[now].hplus);
sgt[now].plus=sgt[now].hplus=;
assert(sgt[now].maxv==max(sgt[lch].maxv,sgt[rch].maxv));
}
void Build_sgt(int now,int l,int r)
{
sgt[now].plus=;
sgt[now].hplus=;
sgt[now].maxv=;
if (l==r)return ;
Build_sgt(lch,l,smid);
Build_sgt(rch,smid+,r);
}
void Add_sgt(int now,int l,int r,int x,int y,qword v)
{
if (l==x && r==y)
{
make_plus(now,v);
return ;
}
down(now);
if (y<=smid)
Add_sgt(lch,l,smid,x,y,v);
else if (smid<x)
Add_sgt(rch,smid+,r,x,y,v);
else
{
Add_sgt(lch,l,smid,x,smid,v);
Add_sgt(rch,smid+,r,smid+,y,v);
}
sgt[now].nmaxv=max(sgt[lch].nmaxv,sgt[rch].nmaxv);
sgt[now].maxv=max(sgt[lch].maxv,sgt[rch].maxv);
}
qword Query_sgt(int now,int l,int r,int pos)
{
if (l==r)
return sgt[now].maxv+sgt[now].plus+sgt[now].hplus;
down(now);
if (pos<=smid)
return Query_sgt(lch,l,smid,pos);
else
return Query_sgt(rch,smid+,r,pos);
}
int Query_sgt(int now,int l,int r,int x,int y)
{
if (l==x && r==y)
return sgt[now].maxv;
down(now);
if (y<=smid)
return Query_sgt(lch,l,smid,x,y);
else if (smid<x)
return Query_sgt(rch,smid+,r,x,y);
else
return max(Query_sgt(lch,l,smid,x,smid),Query_sgt(rch,smid+,r,smid+,y));
}
int a[MAXN],lastid[MAXN*],prv[MAXN];
struct qur_t
{
int l,r,id;
qword ans;
}qur[MAXQ];
bool cmp_r(qur_t q1,qur_t q2)
{
return q1.r<q2.r;
}
bool cmp_id(qur_t q1,qur_t q2)
{
return q1.id<q2.id;
}
int main()
{
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n,m;
scanf("%d",&n);
for (int i=;i<=n;i++)
{
scanf("%d",a+i);
prv[i]=lastid[a[i]+MAXN];
lastid[a[i]+MAXN]=i;
}
scanf("%d",&m);
for (int i=;i<m;i++)
{
scanf("%d%d",&qur[i].l,&qur[i].r);
qur[i].id=i;
}
sort(qur,qur+m,cmp_r);
int qn=;
for (int i=;i<=n;i++)
{
// fprintf(stderr,"%d\n",i);
Add_sgt(,,n,prv[i]+,i,a[i]);
while (qn<m && qur[qn].r==i)
{
qur[qn].ans=Query_sgt(,,n,qur[qn].l,qur[qn].r);
qn++;
}
}
sort(qur,qur+m,cmp_id);
for (int i=;i<m;i++)
printf("%lld\n",qur[i].ans);
}
bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树的更多相关文章
- 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 ...
- 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 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 ...
- SPOJ GSS3 Can you answer these queries III[线段树]
SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...
- 【BZOJ2482】[Spoj1557] Can you answer these queries II 线段树
[BZOJ2482][Spoj1557] Can you answer these queries II Description 给定n个元素的序列. 给出m个询问:求l[i]~r[i]的最大子段和( ...
- SPOJ GSS2 Can you answer these queries II
Time Limit: 1000MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Description Being a ...
- 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]| ≤ ...
随机推荐
- 如何去除CISCO交换机中的口令??
加电后按住交换机前面的那个按钮 灯不闪了以后松手这时交换机会进入switch:模式输入命令 flash然后 dir flash:你会发现有个 config.text 的文件 你的密码和配置都保存在那里 ...
- Java基础知识强化之IO流笔记49:IO流练习之 复制指定目录下指定后缀名的文件并修改名称的案例
1. 复制指定目录下指定后缀名的文件并修改名称的案例 需求:复制指定目录下的指定文件,并修改后缀名. • 指定的文件是:.java文件. • 指定的后缀名是:.jad • 指 ...
- 【邮件】imap与pop3的区别
文:铁乐猫 2015 10月14日 今天替一位在外出差的用户安装和设置完foxmail用于收发邮件,到下午被告知对方用foxmail发完邮件后,在网页上登录邮箱后并没有看到在foxmail中" ...
- 推荐几个对Asp.Net开发者比较实用的工具
推荐几个对Asp.Net开发者比较实用的工具.大家有相关工具也可以在评论区留言,一起努力学习. 工具 1.Visual stdio Productivity Power tool:visual std ...
- 程序员带你学习安卓开发系列-Android文件存储
这是程序员带你学习安卓开发系列教程.本文章致力于面向对象程序员可以快速学习开发安卓技术. 上篇文章:.Net程序员快速学习安卓开发-布局和点击事件的写法 主要讲解了布局和点击事件的写法. 上篇文章补充 ...
- Git之路--1
昨天下午到今天早上,终于搞定了github.过程很难过,不过看到自己的github上有代码了.还是小小的开心了一下.暂时没时间分享相关技术,附带微博链接,有想试试上传上Github的小伙伴可以查看我的 ...
- java ssm框架入门(一)面向接口编程
因为工作上用到spring + strtus2 + mybatis ,所以开始学习下这个框架. 这里用到的是MySQL数据库 首先从web.xml 开始 <?xml version=" ...
- 数据库sharding(scale up to scale out)
sharding是将一个大数据库按照一定规则拆分成多个小数据库的一门技术. 当我们的应用数据量越来越多,访问量越来越大的时候,我们会作何选择?继续提升数据库服务器的性能还是采用一项技术让数据库平滑扩展 ...
- 启动 XPs 代理
Xps代理:扩展了 1 : 运行sp_configure检查代理XPs 的 值. EXEC SP_CONFIGURE 'agent xps'查看run_value 值是否为0,如果为0:需要更改此设置 ...
- 学习笔记_Java_day13_JSP三大指令()
JSP指令 1 JSP指令概述 JSP指令的格式:<%@指令名 attr1=”” attr2=”” %>,一般都会把JSP指令放到JSP文件的最上方,但这不是必须的. JSP ...