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;
}