GSS系列(1)——GSS1&&GSS3
题意:询问一个区间内的最大连续子段和(GSS1),并且有单点修改的操作(GSS2)。
思路:这个题目在老人家的大白鼠里出现过,不过那个是求两个下标,并且相同取更小值。——传的东西更多,判断也稍微繁琐一些。。。
考虑我们平时如何处理最大连续子段和——O(n)DP,然而显然在一个时刻会修改的序列上无法实现。我们至少需要一个O(nlgn)的算法。考虑到这种连续的和可以对应线段树的一些操作,我们就将它应用到线段树上。
老人家在讲子段和的时候提供了一种分治算法——如果将一段序列分成两端,那么它的最大子段和要么完全出现在左边,要么完全出现在右边,要么横跨中点。那么我们可以将线段树维护这么几个状态——这段序列最大前缀(即一定包括序列头),最大后缀(一定包括序列尾),中间最大值(没有什么限制),整段序列和。
对于每一段序列,如何处理它的最大值呢?
在线段树中左右两个儿子分别代表了左序列与右序列,那么构成这个序列最大子序列和要么是左序列的最大要么是右序列的最大要么值左序列后缀加上右序列的前缀——三个判断分别处理即可。(具体看代码
/*==========================================================================
# Last modified: 2016-02-02 15:50
# Filename: GSS1.cpp
# Description:
==========================================================================*/
#define me AcrossTheSky
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#define lowbit(x) (x)&(-x)
#define INF 1000000000
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define maxn 100000
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
/*==================split line==================*/
struct interval{
int sub,sum,suf,pre,v;
}tree[maxn*3];
int L,R,q,n,p;
int a[maxn];
void updata(int node,int l,int r){
if (l==r) {
int x=p;
tree[node].v=x; tree[node].sub=x;
tree[node].pre=x; tree[node].suf=x;
tree[node].sum=x;
return;
}
int mid=rs(l,r),lc=ls(node,0),rc=lc|1;
if (q<=mid) updata(lc,l,mid);
else updata(rc,mid+1,r);
tree[node].sum=tree[lc].sum+tree[rc].sum;
tree[node].pre=max(tree[lc].pre,tree[lc].sum+tree[rc].pre);
tree[node].suf=max(tree[rc].suf,tree[rc].sum+tree[lc].suf); tree[node].sub=max(tree[lc].sub,tree[rc].sub);
tree[node].sub=max(tree[node].sub,tree[lc].suf+tree[rc].pre);
}
void build_tree(int node,int l,int r){
if (l==r) {
int x=a[l];
tree[node].v=x; tree[node].sub=x;
tree[node].pre=x; tree[node].suf=x;
tree[node].sum=x;
return;
}
int mid=rs(l,r),lc=ls(node,0),rc=lc|1;
build_tree(lc,l,mid);build_tree(rc,mid+1,r);
tree[node].sum=tree[lc].sum+tree[rc].sum;
tree[node].pre=max(tree[lc].pre,tree[lc].sum+tree[rc].pre);
tree[node].suf=max(tree[rc].suf,tree[rc].sum+tree[lc].suf); tree[node].sub=max(tree[lc].sub,tree[rc].sub);
tree[node].sub=max(tree[node].sub,tree[lc].suf+tree[rc].pre);
}
void reset(interval &x){
x.sub=-INF; x.v=-INF; x.pre=-INF; x.suf=-INF; x.sum=-INF;
}
interval query(int node,int l,int r){
if (L<=l && r<=R) return tree[node];
int mid=rs(l,r),lc=ls(node,0),rc=lc|1;
interval x,y;
reset(x); reset(y);
x.sum=0; y.sum=0;
if (L<=mid) x=query(lc,l,mid);
if (R>mid) y=query(rc,mid+1,r);
interval ans;
reset(ans);
ans.sub=max(max(x.sub,y.sub),x.suf+y.pre);
ans.suf=max(y.suf,y.sum+x.suf);
ans.pre=max(x.pre,x.sum+y.pre);
ans.sum=x.sum+y.sum;
return ans;
}
int main(){
freopen("a.in","r",stdin);
memset(tree,0,sizeof(tree));
cin >> n;
FOR(q,1,n) scanf("%d",&a[q]);
build_tree(1,1,n);
int m; cin >> m;
FORP(i,1,m){
int t; scanf("%d",&t);
if (t==1){
scanf("%d%d",&L,&R);
printf("%d\n",query(1,1,n).sub);
}
else {
scanf("%d%d",&q,&p);
updata(1,1,n);
}
}
}
GSS系列(1)——GSS1&&GSS3的更多相关文章
- spoj gss1 gss3
传送门 gss1 gss3 spoj gss系列=最大字段和套餐 gss1就是gss3的无单点修改版 有区间查询和单点修改,考虑用线段树维护 我们要维护区间权值和\(s\),区间最大前缀和\(xl\) ...
- SPOJ GSS 系列
来怒做GSS系列了: GSS1:https://www.luogu.org/problemnew/show/SP1043 这题就是维护一个 sum , mx , lmx , rmx,转移时用结构体就好 ...
- spoj GSS系列简要题解
文章目录 GSS1 GSS2 GSS3 GSS4 GSS5 GSS6 GSS7 GSS8 传送门 这个GSSGSSGSS系列全部是跟子段有关的数据结构菜题. 于是来水一篇博客. GSS1 传送门 题意 ...
- SPOJ GSS系列
众所周知的仅次于ynoi的毒瘤数据结构系列.(跟Qtree系列并列?) GSS1: 长度为 $n$ 的序列 $a$,$m$ 个询问,每次询问区间 $[l,r]$ 之间的最大子段和. $1\le n,m ...
- SPOJ GSS系列(数据结构维护技巧入门)
题目链接 GSS $GSS1$ 对于每个询问$l$, $r$,查询$a_{l}$, $a_{l+1}$, $a_{l+2}$, ..., $a_{r}$这个序列的最大字段和. 建立线段树,每个节点维护 ...
- SPOJ - GSS1&&GSS3
GSS1 #include<cstdio> #include<iostream> #define lc k<<1 #define rc k<<1|1 u ...
- GSS 系列题解
GSS GSS1 随便猫树或者线段树,就可以过了 猫树不说,线段树可以维护左边最大,右边最大,区间最大,区间值然后就做出来了. //Isaunoya #pragma GCC optimize(2) # ...
- 激!GSS系列
#include <cstdio> ; ; inline int max(int, int); inline int getint(); inline void putint(int); ...
- SPOJ GSS1 && GSS3 (无更新/更新单点,并询问区间最大连续和)
http://www.spoj.com/problems/GSS1/ 题意:无更新询问区间最大连续和. 做法:线段树每个节点维护sum[rt],maxsum[rt],lsum[rt],rsum[rt] ...
随机推荐
- ZeroMQ(java)之负载均衡
我们在实际的应用中最常遇到的场景如下: A向B发送请求,B向A返回结果.... 但是这种场景就会很容易变成这个样子: 很多A向B发送请求,所以B要不断的处理这些请求,所以就会很容易想到对B进行扩展,由 ...
- 对比WDCP面板与AMH面板的区别与选择
转载: http://www.laozuo.org/2760.html | 老左博客 随着VPS主机的性价比提高(其实就是降价)我们很多站长会越来越多的选择使用VPS搭建网站或者运营一些项目,相比较而 ...
- macbook air 安装win7双系统
转自: http://jingyan.baidu.com/article/6d704a13f99f1a28da51ca49.html 1)遇到“No bootable device-insert bo ...
- calico for kubernetes
(这一篇中很多错误,勿参考!) The reference urls: https://github.com/kubernetes/kubernetes/blob/master/docs/gettin ...
- iOS tableview 选中Cell后的背景颜色和文字颜色
做下记录,备忘 改文字颜色其实是UILabel的属性,改背景颜色是cell的属性,都和tableview无关. cell.textLabel.textColor = BAR_COLOR; cell.t ...
- sqlcmd
使用sqlcmd可以在批处理脚本中执行SQL.虽然这个命令的参数很多,但幸运的是,我们不需要全部理解,在这里简要介绍以下几个: { -U login_id [ -P password ] } | –E ...
- BFS:Meteor Shower(POJ 3669)
奔跑吧,傻牛 题目大意:这只Bessie的牛又要来闹事了,这次她的任务就是来躲流星雨,流星雨就是在一定时间会从天上砸到Bessie的所在的正方形区域内(Bessie在0,0的位置),然后砸下 ...
- Androidi性能优化之Java代码优化(摘自Android性能优化一书)
代码优化不是应用开发的首要任务,提供良好的用户体验并专注于代码的可维护性,这才是你的首要任务.事实上,代码优化应该是最后才做,甚至完全可能不去做,不过,良好的优化可以使程序性能直接达到一个可接受的水平 ...
- 小吃(codevs 3231)
3231 小吃 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 这里简直是吃货的天堂,小吃太多了. ...
- Mysql DDL与DML
1,文件导入:LOAD DATA INFILE '/tmp/pet.txt' INTO TABLE pet FIELDS TERMINATED BY ',' LINES TERMINATED BY ' ...