【BZOJ2482】[Spoj1557] Can you answer these queries II 线段树
【BZOJ2482】[Spoj1557] Can you answer these queries II
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
题解:还是考虑这点:每个子串都是某个前缀的后缀,所以我们依旧枚举每个前缀,用线段树维护它的所有后缀。
出现两次只算一次怎么办?只需要在扫到一个数的时候将它上一个出现的位置变成0即可,这样就会改边很多后缀的值,用线段树去维护。
但是本题求的是最大连续子段和啊,其实只需要维护每个后缀的历史最大值就可以了。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lson x<<1
#define rson x<<1|1
using namespace std;
const int maxn=100010;
typedef long long ll;
int n,m;
int last[maxn<<1],pre[maxn],v[maxn];
ll ans[maxn];
struct node
{
ll t,ht,s,hs;
}s[maxn<<2];
struct QUERY
{
int l,r,org;
}q[maxn];
inline void phd(int x,int y)
{
if(y>0) s[x].hs=max(s[x].hs,s[x].s+y),s[x].ht=max(s[x].ht,s[x].t+y);
}
inline void pd(int x,int y)
{
s[x].s+=y,s[x].t+=y;
if(y>0) s[x].hs=max(s[x].hs,s[x].s),s[x].ht=max(s[x].ht,s[x].t);
}
inline void pushdown(int x)
{
if(s[x].ht) phd(lson,s[x].ht),phd(rson,s[x].ht),s[x].ht=0;
if(s[x].t) pd(lson,s[x].t),pd(rson,s[x].t),s[x].t=0;
}
inline void pushup(int x)
{
s[x].s=max(s[lson].s,s[rson].s),s[x].hs=max(s[lson].hs,s[rson].hs);
}
void updata(int l,int r,int x,int a,int b,int c)
{
if(a<=l&&r<=b)
{
pd(x,c);
return ;
}
pushdown(x);
int mid=(l+r)>>1;
if(a<=mid) updata(l,mid,lson,a,b,c);
if(b>mid) updata(mid+1,r,rson,a,b,c);
pushup(x);
}
ll query(int l,int r,int x,int a,int b)
{
if(a<=l&&r<=b) return s[x].hs;
pushdown(x);
int mid=(l+r)>>1;
if(b<=mid) return query(l,mid,lson,a,b);
if(a>mid) return query(mid+1,r,rson,a,b);
return max(query(l,mid,lson,a,b),query(mid+1,r,rson,a,b));
}
bool cmp(const QUERY &a,const QUERY &b)
{
return a.r<b.r;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd();
int i,j;
for(i=1;i<=n;i++) v[i]=rd(),pre[i]=last[v[i]+100000],last[v[i]+100000]=i;
m=rd();
for(i=1;i<=m;i++) q[i].l=rd(),q[i].r=rd(),q[i].org=i;
sort(q+1,q+m+1,cmp);
for(i=j=1;i<=n;i++)
{
updata(1,n,1,pre[i]+1,i,v[i]);
for(;q[j].r==i;j++) ans[q[j].org]=query(1,n,1,q[j].l,i);
}
for(i=1;i<=m;i++) printf("%lld\n",ans[i]);
return 0;
}
【BZOJ2482】[Spoj1557] Can you answer these queries II 线段树的更多相关文章
- BZOJ2482: [Spoj1557] Can you answer these queries II
题解: 从没见过这么XXX的线段树啊... T_T 我们考虑离线做,按1-n一个一个插入,并且维护区间[ j,i](i为当前插入的数)j<i的最优值. 但这个最优值!!! 我们要保存历史的最优值 ...
- 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 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 GSS2 Can you answer these queries II ——线段树
[题目分析] 线段树,好强! 首先从左往右依次扫描,线段树维护一下f[].f[i]表示从i到当前位置的和的值. 然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值. 关于历史最值问题: 标 ...
- Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字
题目链接:点击打开链接 每一个点都是最大值,把一整个序列和都压缩在一个点里. 1.普通的区间求和就是维护2个值,区间和Sum和延迟标志Lazy 2.Old 是该区间里出现过最大的Sum, Oldlaz ...
- SPOJ GSS1_Can you answer these queries I(线段树区间合并)
SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...
- 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 ...
- GSS4 2713. Can you answer these queries IV 线段树
GSS7 Can you answer these queries IV 题目:给出一个数列,原数列和值不超过1e18,有两种操作: 0 x y:修改区间[x,y]所有数开方后向下调整至最近的整数 1 ...
- GSS5 spoj 2916. Can you answer these queries V 线段树
gss5 Can you answer these queries V 给出数列a1...an,询问时给出: Query(x1,y1,x2,y2) = Max { A[i]+A[i+1]+...+A[ ...
随机推荐
- [Unity3D]UI方案及制作细节(NGUI/EZGUI/原生UI系统)
转载请留下本文原始链接,谢谢.本文会不定期更新维护,最近更新于2013.09.17. http://blog.sina.com.cn/s/blog_5b6cb9500101bplv.html ...
- $ gulp watch 运行出错解决方法
$ gulp watch 运行出错解决方法 $ gulp watch 如果你出现了如下报错信息: gulp-notify: [Laravel Elixir] Browserify Fail ...
- Vue 前端路由 vue-router
1.前端路由 后端路由:多页面,服务器端渲染好返回给浏览器. 前端路由:改变url不向服务器发送请求:前端可以监听url变化:前端可以解析url并执行相应操作. 前后端分离:后端只提供API来返回数据 ...
- Spring 测试框架testContext代码举例
import javax.annotation.Resource; import org.junit.Test; import org.springframework.context.annotati ...
- iOS开发-发送邮件(E-mail)方法整理合集(共3种)
前言:在IOS开发中,有时候我们会需要用到邮件发送的功能.比如,接收用户反馈和程序崩溃通知等等.其实这个功能是很常用的,因为我目前就有发送邮件的开发需求,所以顺便整理下IOS发送邮件的方法. IOS原 ...
- 《Mining the Web:Transforming Customer Data into Customer Value》读后札记
<Mining the Web:Transforming Customer Data into Customer Value> <Web数据挖掘:将客户数据转化为客户价值> — ...
- 自己写浏览器和webserver的分析!
自己写浏览器和webserver 在android写一个浏览器 editText:输入网址ip:port/login.html.提交 把域名解析成ip 产生请求行 get login.html /r/ ...
- 利用python批量缩放图片
废话少说,上代码: import matplotlib as mpl mpl.use('Agg') import os import matplotlib.pyplot as plt from sci ...
- Eclips中文版或汉化使用
Eclipse简体中文包下载地址 :http://babel.eclipse.org/babel/ 在上面网站找,下载地址应该是(注意对应的版本): http://www.eclipse.org/do ...
- Hybird App ( 混合模式移动应用)开发初体验
最近1,2个月一直都尝试开发一款Hybird app,遇到了很多问题,谈谈自己的体会. Hybird app (混合模式移动应用),它利用例如安卓端webview组件+HTML5内嵌的方式混合的方式开 ...