• 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
    ",query(1,1,n).sub);
    		}
    		else {
    			scanf("%d%d",&q,&p);
    			updata(1,1,n);
    		}
    	}
    }



    Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.
  • 相关阅读:
    神秘人物之comca —— 是否就是我的前车之鉴
    mfc错误:其原因可能是堆被损坏,这说明**.exe中或它加载的任何DLL
    微信公共平台php用$GLOBALS["HTTP_RAW_POST_DATA"]收不到信息解决方法
    2013蓝桥杯初赛c语言专科组题目与答案
    一道2012腾讯实习生笔试题
    文件版权自动注释,自动备份
    算法学习 三 >> 认识算法的效率(循环设计)
    算法学习 二 >> 结构化与面向对象两种算法设计的简略分析(c++/java)
    HTML入门(一)
    算法学习 一 >> 初识
  • 原文地址:https://www.cnblogs.com/YCuangWhen/p/5188081.html
Copyright © 2020-2023  润新知