线段树 HDU 3397 Sequence operation
来源:互联网 发布:广告词制作软件 编辑:程序博客网 时间:2024/05/17 01:47
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397
代码风格:http://www.notonlysuccess.com/index.php/segment-tree-complete/
题目大意:操作说明:0——把[a,b]区间全部变成0;1——把[a, b]区间全部变成1;2——把[a,b]区间0,1取反;3——输出[a,b]区间1的个数;4——输出[a, b]区间最长连续1的长度
算法:线段树 区间合并
思路:0,1 操作如果不会可以去做一下POJ3367,代码见http://www.notonlysuccess.com/index.php/segment-tree-complete/
同时统计0和1的左边连续个数lsun,lsum,右边连续个数rsun,rsum,区间最长连续个数msun,msum以及区间内1的个数p
0,1操作时,把取反标记清零
2操作:建立数组x[]作为取反标记,并且lsum,rsun互换,rsum,rsun互换,msum, msun互换,p改变
#include"cstdio"#include"cstring"#include"cmath"#include"algorithm"using namespace std;const int Max = 444444;#define lson l, m, rt << 1#define rson m+1, r, rt << 1 | 1#define mid int m = (l+r) >> 1int lsun[Max], rsun[Max], msun[Max];int rsum[Max], lsum[Max], msum[Max];int cover[Max], p[Max], x[Max];void fxor(int rt){ if(cover[rt] != -1) cover[rt] ^= 1; else x[rt] ^= 1;}int max(int a, int b){ return a > b ? a : b;}int min(int a, int b){ return a < b ? a : b;}void PushUp(int l, int r, int rt, int m){ //printf("%d -- %d, rt == %d\n", p[rt << 1 ], p[rt << 1 | 1], rt); p[rt] = p[rt << 1 ] + p[rt << 1 | 1]; rsum[rt] = rsum[rt << 1 | 1]; rsun[rt] = rsun[rt << 1 | 1]; lsum[rt] = lsum[rt << 1]; lsun[rt] = lsun[rt << 1]; if(lsun[rt] == m - (m >> 1)) lsun[rt] += lsun[rt << 1 | 1]; if(lsum[rt] == m - (m >> 1)) lsum[rt] += lsum[rt << 1 | 1]; if(rsun[rt] == m >> 1) rsun[rt] += rsun[rt << 1]; if(rsum[rt] == m >> 1) rsum[rt] += rsum[rt << 1]; msum[rt] = max(max(msum[rt << 1], msum[rt << 1 | 1]), lsum[rt << 1 | 1] + rsum[rt << 1]); msun[rt] = max(max(msun[rt << 1], msun[rt << 1 | 1]), lsun[rt << 1 | 1] + rsun[rt << 1 ]);}void PushDown(int rt, int m){ if(cover[rt] != -1) { cover[rt << 1] = cover[rt << 1 | 1] = cover[rt]; msum[rt << 1] = rsum[rt << 1] = lsum[rt << 1] = p[rt << 1] = cover[rt] * (m - (m >> 1)); msum[rt << 1 | 1] = rsum[rt << 1 | 1] = lsum[rt << 1 | 1] = p[rt << 1 | 1] = cover[rt] * (m >> 1); msun[rt << 1] = rsun[rt << 1] = lsun[rt << 1] = cover[rt] ? 0 : m - (m >> 1); msun[rt << 1 | 1] = rsun[rt << 1 | 1] = lsun[rt << 1 | 1] = cover[rt] ?0 : m >> 1; x[rt << 1] = x[rt << 1 | 1] = 0; cover[rt] = -1; } if(x[rt] != 0) { fxor(rt << 1); fxor(rt << 1 | 1); p[rt << 1] = (m - (m >> 1)) - p[rt << 1]; p[rt << 1 | 1] = (m >> 1) - p[rt << 1 | 1]; int k = lsum[rt << 1]; lsum[rt << 1] = lsun[rt << 1]; lsun[rt << 1] = k; k = rsum[rt << 1]; rsum[rt << 1] = rsun[rt << 1]; rsun[rt << 1] = k; k = msum[rt << 1]; msum[rt << 1] = msun[rt << 1]; msun[rt << 1] = k; k = lsum[rt << 1 | 1]; lsum[rt << 1 | 1] = lsun[rt << 1 | 1]; lsun[rt << 1 | 1] = k; k = rsum[rt << 1 | 1]; rsum[rt << 1 | 1] = rsun[rt << 1 | 1]; rsun[rt << 1 | 1] = k; k = msum[rt << 1 | 1]; msum[rt << 1 | 1] = msun[rt << 1 | 1]; msun[rt << 1 | 1] = k; x[rt] = 0; }}void build(int l, int r, int rt){ if(l == r) { scanf("%d", &p[rt]); rsum[rt] = msum[rt] = lsum[rt] = p[rt] ? 1 : 0; rsun[rt] = msun[rt] = lsun[rt] = p[rt] ? 0 : 1; //printf("msum[rt] = %d\n", msum[rt]); return ; } mid ; build(lson); build(rson); PushUp(m, m+1, rt, r-l+1);}void update(int op, int L, int R, int l, int r, int rt){ if(L <= l && r <= R) { if(op == 2) { p[rt] = r-l+1-p[rt]; int k = lsum[rt]; lsum[rt] = lsun[rt]; lsun[rt] = k; k = rsum[rt]; rsum[rt] = rsun[rt]; rsun[rt] = k; k = msum[rt]; msum[rt] = msun[rt]; msun[rt] = k; fxor(rt); } else { cover[rt] = op; lsum[rt] = msum[rt] = rsum[rt] = p[rt] = op ? r-l+1 : 0; lsun[rt] = msun[rt] = rsun[rt] = op ? 0 : r-l+1; x[rt] = 0; } return ; } mid ; PushDown(rt, r-l+1); if(L <= m) update(op, L, R, lson); if(m < R) update(op, L, R, rson); PushUp(m, m+1, rt, r-l+1);}int query(int L, int R, int l, int r, int rt){ if(L <= l && r <= R) { return p[rt]; } int ret = 0; PushDown(rt, r-l+1); mid; if(L <= m) ret += query(L, R, lson); if(m < R) ret += query(L, R, rson); return ret ;}int Query(int L, int R, int l, int r, int rt){ if(L <= l && r <= R) { return msum[rt]; } mid; PushDown(rt, r-l+1); if(m < L) return Query(L, R, rson); else if(R <= m) return Query(L, R, lson); return max(max(min(rsum[rt << 1], m+1-L) + min(lsum[rt << 1 | 1], R-m), Query(L, R, lson)), Query(L, R, rson) );}int main(){ int T, n, m; scanf("%d", &T); while( T --) { memset(x, 0, sizeof(x)); memset(cover, -1, sizeof(cover)); scanf("%d%d", &n, &m); build(0, n-1, 1); while(m --) { int a, b, c; scanf("%d%d%d", &a, &b, &c); if(a < 3) update(a, b, c, 0, n-1, 1); else if(a == 3) printf("%d\n", query(b, c, 0, n-1, 1)); else printf("%d\n", Query(b, c, 0, n-1, 1)); } } return 0;}
- 线段树 HDU 3397 Sequence operation
- HDU 3397 Sequence operation (线段树)
- HDU 3397 Sequence operation (线段树)
- HDU 3397 Sequence operation (线段树)
- hdu 3397 Sequence operation 线段树
- hdu 3397 Sequence operation 线段树
- HDU 3397 Sequence operation(线段树)
- HDU 3397 Sequence operation 线段树
- hdu 3397 Sequence operation 线段树
- hdu 3397 Sequence operation(线段树)
- HDU 3397 Sequence operation(线段树)
- HDU - 3397 Sequence operation(线段树)
- hdu 3397 Sequence operation(线段树)
- HDU 3397 Sequence operation 线段树(区间合并)
- hdu 3397 Sequence operation(线段树的各种操作)
- hdu 3397 线段树前后缀blahblah Sequence operation
- hdu 3397 Sequence operation(很有意思的线段树题)
- hdu 3397 Sequence operation(线段树,lazy,区间合并)
- 多线程四 经典线程同步之互斥量Mutex
- Kademlia详解
- UIView 的 autoresizingMask 属性 详解。
- 多线程例子_幂计算而后求和
- ubuntu10.04手动安装gcc4.5
- 线段树 HDU 3397 Sequence operation
- 给定一个N位数,得到一个N-k位的数中最小的数
- 74HC00多谐振荡器的制作
- 常见的流媒体传输协议
- 嵌入式系统的抗干扰与容错设计
- MySQL Show命令的使用
- 对学习计算机专业的人一些忠告
- 发个码农的求职总结
- c++各种类型变量的内存分配