Can you answer these queries?
GSS系列是spoj出品的一套数据结构好毒瘤题,主要以线段树、平衡树和树链剖分为背景,进行了一些操作的魔改,使得难度远超模板题,但对于思维有极大的提升。
所以我会选择一些在我能力范围内的题挖坑选讲,构成一个GSS系列。至于剩下那些,等我成为巨佬弄懂了再说吧。
GSS3:带单点修改的区间最大子段和
本文有前置芝士:GSS1。做法点这里
题意
原题传送门
给定一个序列,单点修改值,区间询问最大子段和
口胡
由于与GSS1太像了,所以本文只有简单的口胡,没有图解。
本题在GSS1上加了一个单点修改,但对实际思想和解法并无影响,因为修改之前要push_down,修改之后要push_up,这些操作都可以很好地维护节点的信息,根本不需要另做考虑。
在update查询到叶节点时,把节点的四个信息修改成一样即可,所以这题也可以支持区间修改。
代码
#include <bits/stdc++.h>
#define MAXN 50005
#define lc(x) (x<<1)
#define rc(x) (x<<1|1)
#define mid ((l+r)>>1)
using namespace std;
struct node{
int sum, ls, rs, ms; //区间和,分别从左右端点开始的最大子段和,区间最大子段和
};
int n, m, val[MAXN];
node a[MAXN*4];
void push_up(int p){
a[p].sum = a[lc(p)].sum + a[rc(p)].sum;
a[p].ls = max(a[lc(p)].ls, a[lc(p)].sum+a[rc(p)].ls);
a[p].rs = max(a[rc(p)].rs, a[rc(p)].sum+a[lc(p)].rs);
a[p].ms = max(max(a[lc(p)].ms, a[rc(p)].ms), a[lc(p)].rs + a[rc(p)].ls);
}
void build(int p, int l, int r){
if(l == r){
a[p].sum = a[p].ls = a[p].rs = a[p].ms = val[l];
return;
}
build(lc(p), l, mid);
build(rc(p), mid+1, r);
push_up(p);
}
void update(int p, int l, int r, int u, int k){
if(l == u && r == u){
a[p].sum = a[p].ls = a[p].rs = a[p].ms = k;
return;
}
if(mid >= u){
update(lc(p), l, mid, u, k);
}
else{
update(rc(p), mid+1, r, u, k);
}
push_up(p);
}
node query(int p, int l, int r, int ul, int ur){
if(l>=ul && r<=ur){
return a[p];
}
if(ul > mid){
return query(rc(p), mid+1, r, ul, ur);
}
if(ur <= mid){
return query(lc(p), l, mid, ul, ur);
}
node res, tl, tr;
tl = query(lc(p), l, mid, ul, ur);
tr = query(rc(p), mid+1, r, ul, ur);
res.sum = tl.sum + tr.sum;
res.ls = max(tl.ls, tl.sum+tr.ls);
res.rs = max(tr.rs, tr.sum+tl.rs);
res.ms = max(max(tl.ms, tr.ms), tl.rs+tr.ls);
return res;
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++){
scanf("%d", &val[i]);
}
build(1, 1, n);
cin >> m;
int t, x, y;
while(m--){
scanf("%d%d%d", &t, &x, &y);
if(!t){
update(1, 1, n, x, y);
}
else{
printf("%d\n", query(1,1,n, x, y).ms);
}
}
return 0;
}
What to do next?
GSS2和GSS5。这两题都是在最大子段和的基础上进行了一些限制,能让你进一步拓展思维。
当然,如果觉得这两题太难,可以先做稍稍简单一些的GSS4。这是一道数据结构与暴力结合的好题。