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/problems/GSS2/
Description
Being a completist and a simplist, kid Yang Zhe cannot solve but get Wrong Answer from most of the OI problems. And he refuse to write two program of same kind at all. So he always failes in contests.
When having a contest, Yang Zhe looks at the score of every problems first. For the problems of the same score, Yang Zhe will do only one of them. If he's lucky enough, he can get all the scores wanted.
Amber is going to hold a contest in SPOJ. She has made a list of N candidate problems, which fit Yang Zhe very well. So Yang Zhe can solve any problem he want. Amber lined up the problems, began to select. She will select a subsequence of the list as the final problems. Being A girl of great compassion, she'd like to select such a subsequence (can be empty) that Yang Zhe will get the maximal score over all the possible subsequences.
Amber found the subsequence easily after a few minutes. To make things harder, Amber decided that, Yang Zhe can take this contest only if Yang Zhe can answer her Q questions. The question is: if the final problems are limited to be a subsequence of list[X..Y] (1 <= X <= Y<= N), what's the maximal possible score Yang Zhe can get?
As we know, Yang Zhe is a bit idiot (so why did he solve the problem with a negative score?), he got Wrong Answer again... Tell him the correct answer!
Input
- Line 1: integer N (1 <= N <= 100000);
- Line 2: N integers denoting the score of each problem, each of them is a integer in range [-100000, 100000];
- Line 3: integer Q (1 <= Q <= 100000);
- Line 3+i (1 <= i <= Q): two integers X and Y denoting the ith question.
Output
- Line i: a single integer, the answer to the ith question.
Sample Input
9
4 -2 -2 3 -1 -4 2 2 -6
3
1 2
1 5
4 9
Sample Output
4
5
3
HINT
题意
给你n个数,查询区间最大连续子段和,并且区间内相同的数只计算一次
题解:
没有修改操作,很明显的离线线段树
假设我们不考虑相同的数只计算一次的规则,我们应该怎么做呢?
对于不断增加的r,我们维护c[i]表示从a[i]-a[r]的和,很显然,我们输出历史中最大的max(c[l],c[l+1],c[l+2]....c[r])就是答案了
想一想感觉挺蠢的。。。
我们怎么维护区间内相同的数只计算一次呢?对于每个数,我们只维护(pre[a[i]]+1,i)这个区间就好了嘛
然后这道题就解决了
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long SgTreeDataType;
struct treenode
{
int L , R ;
SgTreeDataType sum , lazy, cursum, prelazy;
void updata(SgTreeDataType v)
{
sum += v;
lazy += v;
cursum = max(cursum,sum);
prelazy = max(prelazy,lazy);
}
}; treenode tree[]; inline void push_down(int o)
{
SgTreeDataType Prelazy = tree[o].prelazy;
SgTreeDataType Lazy = tree[o].lazy;
tree[*o].prelazy = max(tree[*o].prelazy,tree[o*].lazy + Prelazy);
tree[*o].cursum = max(tree[*o].cursum,tree[o*].sum + Prelazy);
tree[*o].lazy += Lazy; tree[*o].sum += Lazy;
tree[*o+].prelazy = max(tree[*o+].prelazy,tree[o*+].lazy + Prelazy);
tree[*o+].cursum = max(tree[*o+].cursum,tree[o*+].sum + Prelazy);
tree[*o+].lazy += Lazy; tree[*o+].sum += Lazy;
tree[o].lazy = ,tree[o].prelazy = ;
} inline void push_up(int o)
{
tree[o].sum = max(tree[*o].sum,tree[*o+].sum);
tree[o].cursum = max(tree[*o].cursum,tree[*o+].cursum);
} inline void build_tree(int L , int R , int o)
{
tree[o].L = L , tree[o].R = R,tree[o].sum = tree[o].lazy = tree[o].prelazy = tree[o].cursum = ;
if (R > L)
{
int mid = (L+R) >> ;
build_tree(L,mid,o*);
build_tree(mid+,R,o*+);
}
} inline void updata(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR)
tree[o].updata(v);
else
{
push_down(o);
int mid = (L+R)>>;
if (QL <= mid) updata(QL,QR,v,o*);
if (QR > mid) updata(QL,QR,v,o*+);
push_up(o);
}
} inline SgTreeDataType query(int QL,int QR,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) return tree[o].cursum;
else
{
push_down(o);
int mid = (L+R)>>;
SgTreeDataType res = ;
if (QL <= mid) res =max(res, query(QL,QR,*o));
if (QR > mid) res =max(res,query(QL,QR,*o+));
push_up(o);
return res;
}
} int n,m;
int a[];
struct node
{
int l,r,id;
};
bool cmp(node A,node B)
{
return A.r<B.r;
}
node Query[];
int pos[];
long long ans[];
int main()
{
memset(pos,,sizeof(pos));
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
build_tree(,n,);
for(int i=;i<m;i++)
{
scanf("%d%d",&Query[i].l,&Query[i].r);
Query[i].id = i;
}
sort(Query,Query+m,cmp);
int N = ;
for(int i=,j=;i<=n;i++)
{
updata(pos[a[i]+N]+,i,a[i],);
pos[a[i]+N]=i;
while(j<m&&Query[j].r==i)
{
ans[Query[j].id]=query(Query[j].l,Query[j].r,);
j++;
}
}
for(int i=;i<m;i++)
printf("%lld\n",ans[i]);
}
SPOJ 1557. Can you answer these queries II 线段树的更多相关文章
- Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字
题目链接:点击打开链接 每一个点都是最大值,把一整个序列和都压缩在一个点里. 1.普通的区间求和就是维护2个值,区间和Sum和延迟标志Lazy 2.Old 是该区间里出现过最大的Sum, Oldlaz ...
- 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 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 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]| ≤ ...
- 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[ ...
- SPOJ 2916 Can you answer these queries V(线段树-分类讨论)
题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出一个数列.每次查询最大子段和Sum[i,j],其中i和j满足x1<=i<=y1,x2<=j& ...
- SPOJ GSS1 Can you answer these queries I[线段树]
Description You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A q ...
随机推荐
- 四、oracle基本sql语句和函数详解
一.oracle常用数据类型 一. 数据定义语言(ddl) 数据定义语言ddl(data definition language)用于改变数据库结构,包括创建.更改和删除数据库对象. 用于操纵表结构 ...
- android学习笔记六
Android中Activity的Intent大全 Api Level 3: (SDK 1.5) android.intent.action.ALL_APPS android.intent.actio ...
- winfrom dataGridView 自定义分页实现
Winfrom 基本处于忘光的阶段.先需要做个winfrom 的软件.然后自己扩展了DataGridView带分页的控件.废话不多说 上图先 现在一步步实现其效果. 1.添加用户控件 上图即可知道 ...
- CMake实践(2)
一,本期目标: [~@localhost t2]$ cat README this is README├── CMakeLists.txt├── COPYRIGHT├── doc│ └── hel ...
- 2014年acm亚洲区域赛·鞍山站
今天北京赛站的比赛也结束了···看了一天的直播之后意识到鞍山站的比赛都过去了一个多月了···这一个月比较萎靡···整天都在睡觉写报告画工图中度过··· 鞍山比哈尔滨还是暖和很多的···就是山上有奇怪的 ...
- tools/adb: No such file or directory
运行adb出现这种错误: bash: ./adb: No such file or directory 但adb确实存在.那说明你用的是64位的Linux,没装32位运行时库,安装 $ sudo ...
- Jin Ge Jin Qu hao
题意: n首歌和一首经典歌已知其长度,一首歌开始唱必须唱完,现在已知剩余时间,求最多能唱歌的个数并保证唱歌时间总长最大 分析: 留最后一个时间唱经典,然后对剩下的时间用背包求出最大个数,并求出总长最大 ...
- ASP.NET中常用的字符串分割函数
asp.net字符串分割函数用法 先来看个简单的实例 但是其数组长度却是25,而不是3.下面这种方法是先将“[111cn.net]”替换成一个特殊字符,比如$,在根据这个字符执行Split 例如下面我 ...
- mapreduce优化总结
集群的优化 1.合理分配map和reduce任务的数量(单个节点上map任务.reduce任务的最大数量) 2.其他配置 io.file.buffer.size hadoop访问文件的IO操作都需要通 ...
- ASM中的别名
在ASM中的别名,是为了方便管理. 在ASM中创建别名,一种是在RDBMS中创建,另外一种是在ASM中创建,区别就是在ASM中创建的别名,在RDBMS中是不可见的. 在RDBMS中创建别名: SQL& ...