题目链接  Problem D

这个题类似 SPOJ GSS3

做过那个题之后其实就可以秒掉这题了。

考虑当前线段树维护的结点

在那道题的基础上,这个题要多维护几个东西,大概就是左端点的奇偶性,右端点的奇偶性。

以及当前结点代表的区间是否是一个有效的子序列。

时间复杂度$O(nlogn)$

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define ls i << 1
#define rs i << 1 | 1
#define mid ((l + r) >> 1)
#define lson ls, l, mid
#define rson rs, mid + 1, r typedef long long LL; const int N = 1e5 + 10; struct node{
LL c, lc, rc, ret;
int lo, ro, flag;
} t[N << 2]; int n, m; void pushup(int i){
t[i].c = t[ls].c + t[rs].c;
t[i].ret = max(t[ls].ret, t[rs].ret);
t[i].flag = 0;
t[i].lc = t[ls].lc;
t[i].rc = t[rs].rc;
t[i].lo = t[ls].lo;
t[i].ro = t[rs].ro; if (t[ls].ro ^ t[rs].lo){
t[i].ret = max(t[i].ret, t[ls].rc + t[rs].lc);
if (t[ls].flag) t[i].lc = max(t[i].lc, t[ls].c + t[rs].lc);
if (t[rs].flag) t[i].rc = max(t[i].rc, t[rs].c + t[ls].rc);
if (t[ls].flag && t[rs].flag) t[i].flag = 1;
}
} void build(int i, int l, int r){
if (l == r){
scanf("%lld", &t[i].ret);
t[i].c = t[i].lc = t[i].rc = t[i].ret;
t[i].lo = t[i].ro = (t[i].ret & 1);
t[i].flag = 1;
return;
} build(lson);
build(rson);
pushup(i);
} void update(int i, int l, int r, int x, LL val){
if (l == x && l == r){
t[i].ret = t[i].c = t[i].lc = t[i].rc = val;
t[i].lo = t[i].ro = (val & 1);
t[i].flag = 1;
return;
} if (x <= mid) update(lson, x, val);
else update(rson, x, val);
pushup(i);
} node query(int i, int l, int r, int L, int R){
if (L <= l && r <= R) return t[i]; if (R <= mid) return query(lson, L, R);
if (L > mid) return query(rson, L, R); node ta = query(lson, L, mid);
node tb = query(rson, mid + 1, R); node ans;
ans.c = ta.c + tb.c;
ans.ret = max(ta.ret, tb.ret);
ans.flag = 0;
ans.lc = ta.lc;
ans.rc = tb.rc;
ans.lo = ta.lo;
ans.ro = tb.ro;
if (ta.ro ^ tb.lo){
ans.ret = max(ans.ret, ta.rc + tb.lc);
if (ta.flag) ans.lc = max(ans.lc, ta.c + tb.lc);
if (tb.flag) ans.rc = max(ans.rc, tb.c + ta.rc);
if (ta.flag && tb.flag) ans.flag = 1;
} return ans;
} int main(){ scanf("%d%d", &n, &m);
build(1, 1, n); while (m--){
int op;
scanf("%d", &op);
if (op == 0){
int x, y;
scanf("%d%d", &x, &y);
node ans = query(1, 1, n, x, y);
printf("%lld\n", ans.ret);
} else{
int x;
LL y;
scanf("%d%lld", &x, &y);
update(1, 1, n, x, y);
}
} return 0;
}

  

05-07 15:11