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 ...
随机推荐
- 利用ioctl()获取无线速率
其实对于自己装了网卡驱动的来说,应该从最根本的驱动中获取速率. 但是用ioctl()也可以,其实实现和iwconfig命令相同. 仅仅获取速率这部分: #include <stdio.h> ...
- 获取json中字段,判断是否有想要的key
if(json.containsKey("key")){ String refundSid = json.getString("key"); } 如果也要判断v ...
- 将VLC库封装为duilib的万能视频播放控件
转载请说明出处,谢谢~~ 昨天封装好了基于webkit的浏览器控件,修复了duilib的浏览器功能的不足,而我的仿酷狗播放器项目中不光需要浏览器,同时也需要视频播放功能,也就是完成MV的功能.所以我打 ...
- 【windows核心编程】使用远程线程注入DLL
前言 该技术是指通过在[目标进程]中创建一个[远程线程]来达到注入的目的. 创建的[远程线程]函数为LoadLibrary, 线程函数的参数为DLL名字, 想要做的工作在DLL中编写. 示意图如下: ...
- rfid 门卡系统和人体红外感应开发
今天忙了一天了,因为毕昇杯我发现如果不加把劲,可能寒假之前代码搞不出了,今天突击了两个模块,一个人体感应模块,和rfid刷卡模块,这两个模块谈不上自己编写代码,今天的任务也仅仅是看懂了代码,现在我总结 ...
- andriod的简单用法1
1.从一个Activity跳转到另一个Activity,使用Intent. 在按钮的onClick中如下写法: public void Login(View view) { Intent intent ...
- 在ASM中移动数据文件
实验目的:在ASM存储环境下,要删除一个磁盘组,从而将磁盘组中的数据文件移动到另外一个磁盘组中. 查看数据文件存放的位置: SQL> select file#,name from v$dataf ...
- bzoj 1419 Red is good(期望DP)
[题意] R红B蓝,选红得1选蓝失1,问最优状态下的期望得分. [思路] 设f[i][j]为i个Rj个B时的最优期望得分,则有转移式为: f[i][j]=max{ 0,(f[i-1][j]+1)*(i ...
- Install_ruby
Install rvm 1 2 3 $ curl -L get.rvm.io | bash -s stable $ source ~/.bashrc $ source ~/.bash_profile ...
- YARN应用场景、原理与资源调度
1.Hadoop YARN产生背景 源于MapReduce1.0 运维成本 如果采用“一个框架一个集群”的模式,则可能需要多个管理员管理这些集群,进而增加运维成本,而共享模式通常需要少数管理员即可完成 ...