利用线段树求最大连续子序列和

#include <bits/stdc++.h>

using namespace std;

struct Node
{
    int Pre, Max, Suf,Sum;

    int Left, Right;

};

struct Node SegTree[100];
int c[100] = {0,45,88,5,2,-8,-7,88,-9};

void Built(int k, int L, int R)
{
    SegTree[k].Left = L;
    SegTree[k].Right = R;
    if(L == R)
    {
        SegTree[k].Max = c[L];
        SegTree[k].Suf = c[L];
        SegTree[k].Pre = c[L];
        SegTree[k].Sum = c[L];
        return;
    }

    int Mid = (SegTree[k].Left+SegTree[k].Right)/2;
    Built(k<<1, L, Mid);
    Built(k<<1 | 1, Mid+1, R);

    SegTree[k].Max = max(max(SegTree[k<<1].Max, SegTree[k<<1 | 1].Max),
                         SegTree[k<<1].Suf+SegTree[k<<1 | 1].Pre);

    SegTree[k].Suf = SegTree[k<<1 | 1].Suf;
    if(SegTree[k<<1 | 1].Suf == SegTree[k<<1 | 1].Sum)
        SegTree[k].Suf = max(SegTree[k].Suf, SegTree[k<<1 | 1].Max+SegTree[k<<1].Suf);

    SegTree[k].Pre = SegTree[k<<1].Pre;
    if(SegTree[k<<1].Pre == SegTree[k<<1].Sum)
        SegTree[k].Pre = max(SegTree[k].Pre, SegTree[k<<1].Max+SegTree[k<<1 | 1].Pre);

    SegTree[k].Sum = SegTree[k<<1].Sum + SegTree[k<<1 | 1].Sum;
}

void Updata(int k, int dir, int num)
{
    if(SegTree[k].Left == SegTree[k].Right)
    {
        SegTree[k].Max = num;
        SegTree[k].Pre = num;
        SegTree[k].Suf = num;
        SegTree[k].Sum = num;
        return;
    }

    int Mid = (SegTree[k].Left + SegTree[k].Right)/2;

    if(dir <= Mid)
        Updata(k<<1, dir, num);
    if(dir > Mid)
        Updata(k<<1 | 1, dir, num);

    SegTree[k].Max = max(max(SegTree[k<<1].Max , SegTree[k<<1 | 1].Max),
                         SegTree[k<<1].Suf + SegTree[k<<1 | 1].Pre);
    SegTree[k].Pre = SegTree[k<<1].Pre;
    if(SegTree[k<<1].Pre == SegTree[k<<1].Sum)
            SegTree[k].Pre = max(SegTree[k].Pre, SegTree[k<<1].Pre+SegTree[k<<1 | 1].Pre);

    SegTree[k].Suf = SegTree[k<<1 | 1].Suf;
    if(SegTree[k<<1 | 1].Suf == SegTree[k<<1 | 1].Sum)
        SegTree[k].Suf = max(SegTree[k].Suf, SegTree[k<<1 | 1 ].Suf+SegTree[k<<1].Suf);

    SegTree[k].Sum = SegTree[k<<1].Sum + SegTree[k<<1 | 1].Sum;

}

struct Node Query(int k, int L, int R)
{
    if(L <= SegTree[k].Left && SegTree[k].Right <= R)
        return SegTree[k];

    int Mid = (SegTree[k].Left + SegTree[k].Right) >> 1;

    struct Node Node1, Node2, ans;
	int tag1 = 0;
	int tag2 = 0; 
	 
    if(L <= Mid)
    {
    	Node1 = Query(k<<1, L, R);
    	tag1 = 1;
	}
	
	if(Mid < R)
	{
		Node2 = Query(k<<1 | 1, L, R);
		tag2 = 1;
	}	
	
	if(tag1 && tag2)
	{
		ans.Max = max(max(Node1.Max , Node2.Max),
                         Node1.Suf + Node2.Pre);
	    ans.Pre = Node1.Pre;
	    if(Node1.Pre == Node1.Sum)
	            ans.Pre = max(ans.Pre, Node1.Pre+Node2.Pre);
	
	    ans.Suf = Node2.Suf;
	    if(Node2.Suf == Node2.Sum)
	        ans.Suf = max(ans.Suf, Node2.Suf+Node1.Suf);
	
			ans.Sum = Node1.Sum + Node2.Sum;		
		
	}else
	{
		ans = tag1 ? Node1 : Node2;
	}
	
	return ans;    
}

int main(void)
{
    Built(1, 1, 8);

  //  Updata(1, 6, 99);

    cout << Query(1, 2, 5).Max << endl;

    cout << "Yes" <<endl;
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值