Hdu3366sequence operation line segment tree Solution
Question: Click to open the link
Analysis: the interval of the Line Segment tree is updated. It is only mixed with Range Sum, maximum continuous interval sum. The latency tag has already appeared in the previous blog: pojHelp with Intervals line segment tree Solution
Code:
#include
#include#define lc (rt<<1)#define rc (rt<<1|1)#define lson l, m, lc#define rson m + 1, r, rcusing namespace std;const int maxn = 100000 + 10;int unsum[maxn<<2], sum[maxn<<2], lsum[maxn<<2], rsum[maxn<<2], zsum[maxn<<2], lzsum[maxn<<2], rzsum[maxn<<2], col[maxn<<2];void SWAP(int rt, int m){ col[rt] = 1 - col[rt];unsum[rt] = m - unsum[rt];swap(sum[rt], zsum[rt]);swap(lsum[rt], lzsum[rt]);swap(rsum[rt], rzsum[rt]);}void PushUp(int rt, int m){ unsum[rt] = unsum[lc] + unsum[rc]; lsum[rt] = lsum[lc]; rsum[rt] = rsum[rc]; if(lsum[rt] == m - (m>>1)) lsum[rt] += lsum[rc]; if(rsum[rt] == m>>1) rsum[rt] += rsum[lc]; sum[rt] = max(rsum[lc] + lsum[rc], max(sum[lc], sum[rc])); lzsum[rt] = lzsum[lc]; rzsum[rt] = rzsum[rc]; if(lzsum[rt] == m - (m>>1)) lzsum[rt] += lzsum[rc]; if(rzsum[rt] == m>>1) rzsum[rt] += rzsum[lc]; zsum[rt] = max(rzsum[lc] + lzsum[rc], max(zsum[lc], zsum[rc]));}void PushDown(int rt, int m){ if(col[rt] == 2){ col[rt] = 1 - col[rt]; SWAP(lc, m - (m>>1)); SWAP(rc, m>>1); } if(~col[rt]){col[lc] = col[rc] = col[rt]; unsum[lc] = sum[lc] = lsum[lc] = rsum[lc] = col[rt] ? m - (m>>1) : 0; unsum[rc] = sum[lc | 1] = lsum[rc] = rsum[rc] = col[rt] ? m>>1 : 0; zsum[lc] = lzsum[lc] = rzsum[lc] = col[rt] ? 0 : m - (m>>1); zsum[rc] = lzsum[rc] = rzsum[rc] = col[rt] ? 0 : m>>1;col[rt] = -1;}}void build(int l, int r, int rt){ col[rt] = -1; if(l == r){ scanf("%d", &sum[rt]); unsum[rt] = lsum[rt] = rsum[rt] = sum[rt]; zsum[rt] = lzsum[rt] = rzsum[rt] = sum[rt]^1; return; } int m = r + l >> 1; build(lson); build(rson); PushUp(rt, r - l + 1);}void update(int L, int R, int add, int l, int r, int rt){if (L <= l&&r <= R){if(add == 2) SWAP(rt, r - l + 1);else{ col[rt] = add; unsum[rt] = sum[rt] = lsum[rt] = rsum[rt] = add ? r - l + 1 : 0;zsum[rt] = lzsum[rt] = rzsum[rt] = add ? 0 : r - l + 1;}return;}int m = l + r >> 1;PushDown(rt, r - l + 1);if (L <= m) update(L, R, add, lson);if (R > m) update(L, R, add, rson);PushUp(rt, r - l + 1);}int query(int L, int R, int op, int l, int r, int rt){ int m = l + r >> 1, ans = 0; if(op&1){ if(L <= l && r <= R) return unsum[rt]; PushDown(rt, r - l + 1); if(L <= m) ans += query(L, R, op, lson); if(m < R) ans += query(L, R, op, rson); return ans; } if(L <= l && r <= R) return sum[rt]; PushDown(rt, r - l + 1); ans = min(rsum[lc], m - L + 1) + min(lsum[rc], R - m); if(L <= m) ans = max(ans, query(L, R, op, lson)); if(m < R) ans = max(ans, query(L, R, op, rson)); return ans;}int main(){ int n, m, T, op, a, b; scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); build(1, n, 1); while(m--){ scanf("%d%d%d", &op, &a, &b); if(op < 3) update(a + 1, b + 1, op, 1, n, 1); else printf("%d\n", query(a + 1, b + 1, op, 1, n, 1)); } } return 0;}