GSS系列(1)——GSS1&&GSS3
来源:互联网 发布:mac怎么连接vps 编辑:程序博客网 时间:2024/06/04 23:02
题意:询问一个区间内的最大连续子段和(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 100000using 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);}}}
0 0
- GSS系列(1)——GSS1&&GSS3
- spoj GSS系列之GSS1 和 GSS3
- GSS1&GSS3
- SPOJ GSS1 & GSS3&挂了的GSS5
- spoj GSS系列
- SPOJ GSS系列
- spoj GSS系列
- 【SPOJ】GSS系列
- SPOJ GSS1 - Can you answer these queries I(线段树维护GSS)
- SPOJ GSS 1~8
- GSS 1 区间最大子段和
- spoj GSS1
- SPOJ GSS1
- 怒水一记 GSS
- SPOJ GSS
- [SPOJ1043,1557,1716,2713,2916,4487,6779,19543]GSS八题系列
- SPOJ GSS系列 最大子段和 线段树+树链剖分+splay 1043 1557 1716 2713 2916 4487 6779
- SPOJ 1716 Can you answer these queries III(GSS3 线段树)
- 关于spring切面的一点理解,记录一下
- 机顶盒业务相关
- 高德导航断网后恢复网络不重新规划路径问题及解决方案
- java起线程超级简单例子(咋个办呢 zgbn)
- 开涛的springMVC教程读书笔记
- GSS系列(1)——GSS1&&GSS3
- VNC远程桌面到linux,提示connection refused(10061)解决办法
- 简单学习HTTP协议
- 蓝牙4.0 BLE 广播包解析
- 自己不反抗谁能帮得了你?
- doubango中视频JitterBuffer的优化
- Java面向对象的基本知识<一>
- RecyclerView通用Adapter与ViewHolder
- Java实现ping功能的三种方法