咋回事啊,现在才来写这个题?
刚废了一上午,人没了。
这题就是需要维护一下单点修改,区间最大子段和,很容易想到线段树。
线段树中有几个变量:\(val,lmax,rmax,Max\)。
\(val\)表示此节点的和。
\(lmax\)表示从左节点开始的最大子段和
\[lmax = \max \{\sum_{i = l} ^ k a_i | k \le r \} \]上面的\(l,r\)就是这个节点的\(l,r\)。
\(rmax\)同理。
\(Max\)即为最大字段和。
然后就是一堆式子了,详见代码。
话说指针线段树有毒哦,我调了一上午,还是RE。
于是改为数组版,香啊!
#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
int n, m;
int a[N];
struct node
{
int val;
int lmax, rmax, Max;
} T[N << 2];
void Update(int root)
{
T[root].val = T[root << 1].val + T[root << 1 | 1].val;
T[root].lmax = max(T[root << 1].lmax, T[root << 1].val + T[root << 1 | 1].lmax);
T[root].rmax = max(T[root << 1 | 1].rmax, T[root << 1 | 1].val + T[root << 1].rmax);
T[root].Max = max(max(T[root << 1].Max, T[root << 1 | 1].Max), T[root << 1].rmax + T[root << 1 | 1].lmax);
return;
}
void build(int root, int l, int r)
{
if (l == r)
{
T[root].val = T[root].lmax = T[root].rmax = T[root].Max = a[l];
return;
}
int mid = (l + r) >> 1;
build(root << 1, l, mid);
build(root << 1 | 1, mid + 1, r);
Update(root);
}
void update(int root, int x, int l, int r, int delta)
{
if (x == l && x == r)
{
T[root].val = T[root].lmax = T[root].rmax = T[root].Max = delta;
return;
}
int mid = (l + r) >> 1;
if (x >= l && x <= mid)
{
update(root << 1, x, l, mid, delta);
}
else
{
update(root << 1 | 1, x, mid + 1, r, delta);
}
Update(root);
return;
}
node query(int root, int l, int r, int s, int t)
{
if (l <= s && t <= r)
{
return T[root];
}
int mid = (s + t) >> 1;
if (r <= mid)
return query(root << 1, l, r, s, mid);
else
{
if (l > mid)
return query(root << 1 | 1, l, r, mid + 1, t);
else
{
node L = query(root << 1, l, r, s, mid), R = query(root << 1 | 1, l, r, mid + 1, t);
node ans;
ans.val = L.val + R.val;
ans.lmax = max(L.lmax, L.val + R.lmax);
ans.rmax = max(R.rmax, R.val + L.rmax);
ans.Max = max(max(L.Max, R.Max), L.rmax + R.lmax);
return ans;
}
}
}
int main(void)
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
build(1, 1, n);
while (m--)
{
int k, a, b;
scanf("%d%d%d", &k, &a, &b);
if (k == 1)
{
if (a > b)
swap(a, b);
node ans = query(1, a, b, 1, n);
printf("%d\n", ans.Max);
}
else
{
update(1, a, 1, n, b);
}
}
return 0;
}