题目
思路
详细思路移步GSS1这里只是加入了一个单点更新得操作,找到要更新得顶点,然后把它更改,再递归调用回溯的时候维护区间特征值
End
E
n
d
代码
struct Node{
int l, r;
int sum, maxs, maxl, maxr; //区间和, 区间最大子段和, 最大前缀和, 最大后缀和
}tree[maxn<<2];
int num[maxn]; //数值数组
void build(int i, int l, int r){
tree[i].l = l;
tree[i].r = r;
if(l == r){
tree[i].sum = num[l];
tree[i].maxs = num[l];
tree[i].maxl = num[l];
tree[i].maxr = num[l];
return ;
}
int mid = (l+r)>>1;
build(i<<1, l, mid);
build(i<<1|1, mid+1, r); //子树建树后更新特征值
tree[i].sum = tree[i<<1].sum + tree[i<<1|1].sum;
tree[i].maxs = max(max(tree[i<<1].maxs, tree[i<<1|1].maxs), tree[i<<1].maxr+tree[i<<1|1].maxl);
tree[i].maxl = max(tree[i<<1].maxl, tree[i<<1].sum+tree[i<<1|1].maxl);
tree[i].maxr = max(tree[i<<1|1].maxr, tree[i<<1|1].sum+tree[i<<1].maxr);
return ;
}
Node query(int i, int l, int r){
if(tree[i].l==l && tree[i].r==r)
return tree[i];
int mid = (tree[i].l+tree[i].r)>>1;
if(mid >= r)
return query(i<<1, l, r);
else if(mid < l)
return query(i<<1|1, l, r);
else {
Node ls = query(i, l, mid);
Node rs = query(i, mid+1, r);
ls.maxs = max(max(ls.maxs, rs.maxs), ls.maxr+rs.maxl);
ls.maxl = max(ls.maxl, ls.sum+rs.maxl);
ls.maxr = max(rs.maxr, rs.sum+ls.maxr);
ls.sum = ls.sum + rs.sum;
return ls;
}
}
void update(int i, int x, int k){
if(tree[i].l == tree[i].r){
tree[i].sum = k;
tree[i].maxs = k;
tree[i].maxl = k;
tree[i].maxr = k;
return ;
}
int mid = (tree[i].l+tree[i].r)>>1;
if(x<=mid) update(i<<1, x, k);
else update(i<<1|1, x, k);
tree[i].sum = tree[i<<1].sum + tree[i<<1|1].sum;
tree[i].maxs = max(max(tree[i<<1].maxs, tree[i<<1|1].maxs), tree[i<<1].maxr+tree[i<<1|1].maxl);
tree[i].maxl = max(tree[i<<1].maxl, tree[i<<1].sum+tree[i<<1|1].maxl);
tree[i].maxr = max(tree[i<<1|1].maxr, tree[i<<1|1].sum+tree[i<<1].maxr);
}
int main()
{
int n, m;
sd(n);
rep(i, 1, n+1)
sd(num[i]);
build(1, 1, n);
sd(m);
rep(i, 0, m) {
int op, l, r;
sddd(op, l, r);
if(op == 0) update(1, l, r);
else if(op == 1) {
Node ans = query(1, l, r);
printf("%d\n", ans.maxs);
}
}
return 0;
}