设为首页 加入收藏

TOP

HDU3397Sequence operation线段树解法
2015-07-20 17:50:24 来源: 作者: 【 】 浏览:2
Tags:HDU3397Sequence operation 线段 解法

题:点击打开链接

分析:线段树区间更新。只不过掺杂了区间和、最大连续区间区间和。对于延迟标记在上一篇博客已经出现过:pojHelp with Intervals线段树解法

代码:

#include
  
   
#include
   
     #define lc (rt<<1) #define rc (rt<<1|1) #define lson l, m, lc #define rson m + 1, r, rc using 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; } 
   
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇CodeForces 358E - Dima and Kicks 下一篇uva147 - Dollars(完全背包)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·switch520最新的地址 (2025-12-24 19:19:41)
·微信聊天功能使用了 (2025-12-24 19:19:39)
·websocket和普通的so (2025-12-24 19:19:36)
·Python中文网 - 人生 (2025-12-24 18:49:47)
·【整整648集】这绝对 (2025-12-24 18:49:44)