1001. Magician (hdu5316)
这个题目用到线段树来合并区间,题目有句话的意思A beautiful subsequence is a subsequence that all the adjacent pairs of elves in the sequence have a different parity of position说的是相邻的两个元素必须有不同的奇偶位置,所有一个序列有四种可能的形式,奇...奇, 奇...偶,偶...奇, 偶...偶,这四种形式只是端点的奇偶性,所以线段树的每个节点就得有四个值,分别维护这四个值就行了,举个例子来说,根节点的偶偶的最大值取决于 左孩子的偶偶 + 右孩子的奇偶, 左孩子的偶奇 + 右孩子的偶偶, 左孩子的偶偶,右孩子的偶偶, 所以根节点的偶偶就等于他们当中的最大值,同理,其他的三个也是这样,剩下的另外一种操作就是更新点了。
#include<iostream> #include <stdio.h> using namespace std; typedef long long LL; const int maxn = 100010; const LL inf = 1LL << 61; LL d[maxn]; struct Data{ LL s00, s01, s10, s11;//s00表示偶偶, s01表示偶奇, s10表示奇偶,s11表示奇奇 void init() { s00 = s01 = s10 = s11 = -inf;//初始化一定要为负无穷,因为可能有负数 } LL max_ele() { return max(max(s00, s01), max(s10, s11));//找出他们当中最大的 } }; struct tree{ Data data; }; tree sum[maxn * 4];//线段树 void checkmax(LL &a, const LL b) { if (a < b) a = b; } Data operator + (const Data &a, const Data &b) { Data ret; ret.s11 = max(a.s11 + b.s01, a.s10 + b.s11); checkmax(ret.s11, a.s11); checkmax(ret.s11, b.s11); ret.s10 = max(a.s11 + b.s00, a.s10 + b.s10); checkmax(ret.s10, a.s10); checkmax(ret.s10, b.s10); ret.s00 = max(a.s00 + b.s10, a.s01 + b.s00); checkmax(ret.s00, a.s00); checkmax(ret.s00, b.s00); ret.s01 = max(a.s00 + b.s11, a.s01 + b.s01); checkmax(ret.s01, a.s01); checkmax(ret.s01, b.s01); return ret; } void pushup(int rt) { sum[rt].data = sum[rt<<1].data + sum[rt<<1|1].data; } void build(int L, int R, int rt) { sum[rt].data.init(); if (L == R) { if (L & 1) sum[rt].data.s11 = d[L]; else sum[rt].data.s00 = d[L]; return; } int mid = (L + R) / 2; build(L, mid, rt<<1); build(mid + 1, R, rt<<1|1); pushup(rt); } void update(int pos, LL value, int L, int R, int rt) { if (L == pos && R == pos) { if (pos & 1) sum[rt].data.s11 = value; else sum[rt].data.s00 = value; return; } int mid = (L + R) / 2; if (pos <= mid) update(pos, value, L, mid, rt<<1); else update(pos, value, mid + 1, R, rt<<1|1); pushup(rt); } Data query(int l, int r, int L, int R, int rt) { if (l <= L && r >= R) { return sum[rt].data; } int mid = (L + R) >> 1; Data lson, rson; lson.init(); rson.init(); if (l <= mid) lson = query(l, r, L, mid, rt<<1); if (r > mid) rson = query(l, r, mid + 1, R, rt<<1|1); return lson + rson; } int main() { int T, n, m; scanf("%d", &T); while (T--) { scanf("%d %d", &n ,&m); for (int i = 1; i <= n; i++) scanf("%I64d", &d[i]); build(1, n, 1); int op, a, b; for (int i = 0; i < m; i++) { scanf("%d %d %d", &op, &a, &b); if (op) update(a, (LL)b, 1, n, 1); else { Data ans = query(a, b, 1, n, 1); printf("%I64d\n", ans.max_ele()); } } } return 0; }