传送门:SPOJ 1716
题意
求动态区间最大子段和
题解
线段树区间合并维护区间和, 左右连续最大字段和, 最大字段和
AC code:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long ll;
#define lch(x) x << 1
#define rch(x) x << 1 | 1
const int N = 50000 + 5;
struct Node{
ll ans, la, ra, sum;
}R[N << 2];
int n, M;
inline ll max(ll a, ll b) {return a > b ? a : b;}
void pushUp(Node &q, Node q1, Node q2){
q.sum = q1.sum + q2.sum;
q.la = max(q1.la, q1.sum + q2.la);
q.ra = max(q2.ra, q1.ra + q2.sum);
q.ans = max(max(q1.ans, q2.ans), q1.ra + q2.la);
//if(q2.la + q1.sum > q1.la
}
void build(int rt, int l, int r){
if(l == r){
cin >> R[rt].ans;
R[rt].sum = R[rt].la = R[rt].ra = R[rt].ans;
return;
}
int m = (l + r) >> 1;
build(lch(rt), l, m);
build(rch(rt), m + 1, r);
pushUp(R[rt], R[lch(rt)], R[rch(rt)]);
}
void update(int rt, int l, int r, int x, int y){
if(l == r){
R[rt].sum = R[rt].la = R[rt].ra = R[rt].ans = y * 1ll;
return;
}
int m = (l + r) >> 1;
if(x <= m) update(lch(rt), l, m, x, y);
else update(rch(rt), m + 1, r, x, y);
pushUp(R[rt], R[lch(rt)], R[rch(rt)]);
}
Node query(int rt, int l, int r, int x, int y){
if(l == x && r == y) return R[rt];
int m = (l + r) >> 1;
if(x > m) return query(rch(rt), m + 1, r, x, y);
if(y <= m) return query(lch(rt), l, m, x, y);
Node q, q1, q2;
q1 = query(lch(rt), l, m, x, m);
q2 = query(rch(rt), m + 1, r, m + 1, y);
pushUp(q, q1, q2);
return q;
}
int main(){
//freopen("in.txt", "r", stdin);
int op, x, y;
while(cin >> n){
build(1, 1, n);
cin >> M;
while(M--){
cin >> op >> x >> y;
if(!op) update(1, 1, n, x, y);
else cout << query(1, 1, n, x, y).ans << endl;
}
}
return 0;
}