P4513 小白逛公园

题目链接

受到之前一道题的启发
考虑两个子区间合并成一个区间,求该区间的最大和
那么只有这几种可能
左区间的左答案 ,左区间和+右区间左答案
右区间同理
以及左区间的右答案+右区间的左答案

#include <iostream>
#include <algorithm>
using namespace std;

#define MAXN 500005

int val[MAXN],N,M;
struct Node{
    int L,R,sum,ans;
};

inline Node merge(Node a,Node b) {
    Node ans;
    ans.L = max(a.L,a.sum+b.L);
    ans.R = max(b.R,b.sum+a.R);
    ans.ans = max(a.ans,b.ans);
    ans.ans = max(ans.ans,max(ans.L,ans.R));
    ans.ans = max(ans.ans,b.L+a.R);
    ans.sum = a.sum+b.sum; 
    return ans;
}

struct Segment_Tree {
    
	int L[MAXN<<2],R[MAXN<<2],ans[MAXN<<2],sum[MAXN<<2],maxx[MAXN<<2];
    #define lson (rt<<1)
    #define rson (rt<<1|1)

    inline void pushup(int rt) {
        L[rt] = max(L[lson],sum[lson]+L[rson]);
		R[rt] = max(R[rson],sum[rson]+R[lson]);
		ans[rt] = max(ans[lson],ans[rson]);
		ans[rt] = max(ans[rt],max(L[rt],R[rt]));
		ans[rt] = max(ans[rt],R[lson]+L[rson]);
		sum[rt] = sum[lson] + sum[rson];
		maxx[rt] = max(maxx[lson],maxx[rson]);
    }
    void Build(int rt,int l,int r) {
        if(l==r) {
			L[rt] = R[rt] = ans[rt] = sum[rt] = maxx[rt] = val[l];
            return;
        }
        int mid = (l+r) >> 1;
        Build(lson,l,mid);
        Build(rson,mid+1,r);
        pushup(rt);
    }
    void update(long long C,int x,int rt,int l,int r) {
        if(l==r) {
            L[rt] = R[rt] = ans[rt] = sum[rt] = maxx[rt] = C;
            return;
        }
        int mid = (l+r) >> 1;
        if(x<=mid) update(C,x,lson,l,mid); 
        if(x>mid) update(C,x,rson,mid+1,r);
        pushup(rt);
    }
    Node query(int a,int b,int rt,int l,int r) {
        if(a>r||b<l) return (Node){0,0,0,0};
        if(a<=l&&b>=r) return (Node){L[rt],R[rt],sum[rt],ans[rt]};
        int mid = (l+r) >> 1; Node as = (Node){0,0,0,0};
        if(a<=mid) as = merge(as,query(a,b,lson,l,mid)); 
        if(b>mid) as = merge(as,query(a,b,rson,mid+1,r));
        pushup(rt);
        return as;
    }
    long long query_maxx(int L,int R,int rt,int l,int r) {
        if(L>r||R<l) return -2147483648;
        if(L<=l&&R>=r) return maxx[rt];
        int mid = (l+r) >> 1; long long as = -2147483648;
        if(L<=mid) as = max(as,query_maxx(L,R,lson,l,mid)); 
        if(R>mid) as = max(as,query_maxx(L,R,rson,mid+1,r));
        pushup(rt);
        return as;
    }
} T;

int main() {

	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int opt,a,b;
	cin >> N >> M;
	for(int i=1;i<=N;++i) cin >> val[i];
	T.Build(1,1,N);

	for(int i=1;i<=M;++i) {
		cin >> opt >> a >> b;
		if(opt==1) {
			if(a>b) swap(a,b);
			Node temp = T.query(a,b,1,1,N);
			int maxx = T.query_maxx(a,b,1,1,N);
			if(temp.ans==0) cout << maxx << '\n';
			else cout << temp.ans << '\n';
		}
		else T.update(b,a,1,1,N);
	}

	return 0;
}
posted @ 2021-10-28 13:39  Neworld1111  阅读(18)  评论(0编辑  收藏  举报