HDU 3397 Sequence operation
裸线段树区间合并,题目本身不难,就是细节处理比较麻烦。
因为涉及到异或运算,所以连续0和连续1的个数都要记录一下。
操作的懒惰标记我只用了一个flag,注意flag更新时的细节,我分了三种情况:
flag == -1 或者 当前操作为0或1:更新时直接赋值。因为0, 1操作都可以直接覆盖前面的操作。
flag == 0或1,当前操作为2(xor):flag ^= 1。前面标记过0或1,当前操作为异或,那么改变flag标记
flag == 2,当前操作为2(xor): flag = -1。前面只出现过异或运算,没出现过0,1运算。因为异或两次相当于没异或,所以清除标记即可。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 6 using namespace std; 7 8 #define lson l, m, rt << 1 9 #define rson m + 1, r, rt << 1 | 1 10 11 const int MAXN = 100010; 12 13 int N, Q, maxLen; 14 int cnt[ MAXN << 2 ]; // 1 的个数 15 int len[ MAXN << 2 ]; //最长连续1长度 16 int len0[ MAXN << 2 ]; //最长连续0长度 17 int flag[ MAXN << 2 ]; //懒惰标记 18 int Llen[ MAXN << 2 ]; //左端连续1长度 19 int Llen0[ MAXN << 2 ]; //左端连续0长度 20 int Rlen[ MAXN << 2 ]; //右端连续1长度 21 int Rlen0[ MAXN << 2 ]; //右端连续0长度 22 bool Lnode[ MAXN << 2 ]; //左端点是否为1 23 bool Rnode[ MAXN << 2 ]; //右端点是否为1 24 25 void PushUp( int rt, int l, int r, int m ) 26 { 27 int lc = rt << 1; 28 int rc = rt << 1 | 1; 29 30 cnt[rt] = cnt[lc] + cnt[rc]; 31 32 Lnode[rt] = Lnode[lc]; 33 Rnode[rt] = Rnode[rc]; 34 35 Llen[rt] = Llen[lc]; 36 Rlen[rt] = Rlen[rc]; 37 38 Llen0[rt] = Llen0[lc]; 39 Rlen0[rt] = Rlen0[rc]; 40 41 if ( Llen[lc] == m - l + 1 ) Llen[rt] += Llen[rc]; 42 if ( Llen0[lc] == m - l + 1 ) Llen0[rt] += Llen0[rc]; 43 44 if ( Rlen[rc] == r - m ) Rlen[rt] += Rlen[lc]; 45 if ( Rlen0[rc] == r - m ) Rlen0[rt] += Rlen0[lc]; 46 47 len[rt] = max( len[lc], len[rc] ); 48 len0[rt] = max( len0[lc], len0[rc] ); 49 if ( Rnode[lc] && Lnode[rc] ) 50 { 51 len[rt] = max( len[rt], Rlen[lc] + Llen[rc] ); 52 } 53 54 if ( !Rnode[lc] && !Lnode[rc] ) 55 { 56 len0[rt] = max( len0[rt], Rlen0[lc] + Llen0[rc] ); 57 } 58 59 return; 60 } 61 62 void chuli( int op, int rt, int l, int r ) 63 { 64 if ( op == 0 ) 65 { 66 cnt[rt] = 0; 67 Lnode[rt] = Rnode[rt] = false; 68 len[rt] = Llen[rt] = Rlen[rt] = 0; 69 len0[rt] = Llen0[rt] = Rlen0[rt] = r - l + 1; 70 } 71 else if ( op == 1 ) 72 { 73 cnt[rt] = r - l + 1; 74 Lnode[rt] = Rnode[rt] = true; 75 len[rt] = Llen[rt] = Rlen[rt] = r - l + 1; 76 len0[rt] = Llen0[rt] = Rlen0[rt] = 0; 77 } 78 else 79 { 80 cnt[rt] = r - l + 1 - cnt[rt]; 81 Lnode[rt] = !Lnode[rt]; 82 Rnode[rt] = !Rnode[rt]; 83 swap( Llen[rt], Llen0[rt] ); 84 swap( Rlen[rt], Rlen0[rt] ); 85 swap( len[rt], len0[rt] ); 86 } 87 return; 88 } 89 90 void fuzhi( int rt, int c, int l, int r ) 91 { 92 if ( flag[rt] == -1 ) 93 { 94 flag[rt] = c; 95 return; 96 } 97 if ( c == 2 ) 98 { 99 if ( flag[rt] == 0 || flag[rt] == 1 ) flag[rt] ^= 1; 100 else if ( flag[rt] == 2 ) flag[rt] = -1; 101 } 102 else flag[rt] = c; 103 104 return; 105 } 106 107 void PushDown( int rt, int l, int r, int m ) 108 { 109 int lc = rt << 1; 110 int rc = rt << 1 | 1; 111 if ( flag[rt] != -1 ) 112 { 113 if ( flag[rt] == 0 || flag[rt] == 1 ) flag[lc] = flag[rc] = flag[rt]; 114 else 115 { 116 fuzhi( lc, flag[rt], l, m ); 117 fuzhi( rc, flag[rt], m + 1, r ); 118 } 119 chuli( flag[lc], lc, l, m ); 120 chuli( flag[rc], rc, m + 1, r ); 121 flag[rt] = -1; 122 } 123 return; 124 } 125 126 void Build( int l, int r, int rt ) 127 { 128 flag[rt] = -1; 129 if ( l == r ) 130 { 131 int num; 132 scanf( "%d", &num ); 133 if ( num == 1 ) 134 { 135 cnt[rt] = 1; 136 Llen[rt] = Rlen[rt] = len[rt] = 1; 137 Llen0[rt] = Rlen0[rt] = len0[rt] = 0; 138 Lnode[rt] = Rnode[rt] = true; 139 } 140 else 141 { 142 cnt[rt] = 0; 143 Llen[rt] = Rlen[rt] = len[rt] = 0; 144 Llen0[rt] = Rlen0[rt] = len0[rt] = 1; 145 Lnode[rt] = Rnode[rt] = false; 146 } 147 return; 148 } 149 150 int m = ( l + r ) >> 1; 151 Build( lson ); 152 Build( rson ); 153 PushUp( rt, l, r, m ); 154 155 return; 156 } 157 158 void Update( int L ,int R, int c, int l, int r, int rt ) 159 { 160 int m = ( l + r ) >> 1; 161 162 if ( L <= l && r <= R ) 163 { 164 fuzhi( rt, c, l, r ); 165 chuli( flag[rt], rt, l, r ); 166 return; 167 } 168 169 PushDown( rt, l, r, m ); 170 171 if ( L <= m ) Update( L, R, c, lson ); 172 if ( R > m ) Update( L, R, c, rson ); 173 PushUp( rt, l, r, m ); 174 175 return; 176 } 177 178 int Query( int L, int R, int l, int r, int rt ) 179 { 180 181 int m = ( l + r ) >> 1; 182 if ( L <= l && r <= R ) 183 { 184 maxLen = max( maxLen, len[rt] ); 185 return cnt[rt]; 186 } 187 188 PushDown( rt, l, r, m ); 189 190 int ret = 0; 191 if ( L <= m ) ret += Query( L, R, lson ); 192 if ( R > m ) ret += Query( L, R, rson ); 193 194 PushUp( rt, l, r, m ); 195 196 if ( Lnode[rt << 1 | 1] && Rnode[rt << 1] ) 197 maxLen = max( maxLen, min( Llen[rt << 1 | 1], R - m ) + min( Rlen[ rt << 1 ], m - L + 1 ) ); 198 199 200 return ret; 201 } 202 203 int main() 204 { 205 //freopen( "in2.txt", "r", stdin ); 206 //freopen( "out.txt", "w", stdout ); 207 int T; 208 scanf( "%d", &T ); 209 while ( T-- ) 210 { 211 scanf( "%d%d", &N, &Q ); 212 Build( 0, N - 1, 1 ); 213 while ( Q-- ) 214 { 215 int op, a, b; 216 scanf( "%d%d%d", &op, &a, &b ); 217 { 218 if ( op < 3 ) 219 Update(a, b, op, 0, N - 1, 1 ); 220 else 221 { 222 maxLen = 0; 223 int ans = Query( a, b, 0, N - 1, 1 ); 224 if ( op == 3 ) printf( "%d\n", ans ); 225 else printf( "%d\n", maxLen ); 226 } 227 } 228 } 229 } 230 return 0; 231 }
转载于:https://www.cnblogs.com/GBRgbr/archive/2013/05/20/3089504.html
HDU 3397 Sequence operation相关推荐
- HDU 3397 Sequence operation(线段树)
HDU 3397 Sequence operation 题目链接 题意:给定一个01序列,有5种操作 0 a b [a.b]区间置为0 1 a b [a,b]区间置为1 2 a b [a,b]区间0变 ...
- hdu 3397 Sequence operation(线段树,lazy,区间合并)
hdu 3397 Sequence operation 线段树lazy和区间合并结合的一个题,相当于几个题集中到一起嘛,分开想就好了 0,1,2操作都要lazy,2的异或操作找到每一只含1或只含0的区 ...
- HDU 3397 Sequence operation 线段树 成段更新 区间合并
比较综合的题. 两个标记 setv,xorr.setv的优先级高于xorr,当一个节点获得一个setv时,他之前的xorr要清除. //#pragma comment(linker, "/ ...
- HDU - 3397 Sequence operation(线段树+区间合并)
题目链接:点击查看 题目大意:给定一个初始的数列,然后依次进行m次操作: 0 a b:将闭区间[a,b]内的点都变为0 1 a b:将闭区间[a,b]内的点都变为1 2 a b:将闭区间[a,b]内的 ...
- 【线段树】HDU 3397 Sequence operation 区间合并
操作 Change operations: 0 a b change all characters into '0's in [a , b] 1 a b change all characters i ...
- HDU 3397 Sequence operation(线段树区间合并)
题意: 0 a b将区间[a,b]所有数全部变成0 1 a b将区间[a,b]所有数全部变成1 2 a b将区间[a,b]中所有数0 1互换,0变1,1变0 3 a b输出区间[a,b]中1的个数 4 ...
- HDU - 5919 Sequence II——主席树+区间种类++逆序建树
[题目描述] HDU - 5919 Sequence II [题目分析] 题目给定一个数组,每次查询一个区间,找出区间内不同数字的个数x,然后输出按出现顺序第x/2向上取整个数字的位置. 按照要求,我 ...
- Sequence operation HDU - 3397
点击打开链接 写了好久 终于AC 还是对线段树理解不到位 0 1操作是裸区间着色 2操作是裸区间翻转(异或) 对于这两种区间操作各设两个laz变量 3操作是裸区间查询 4操作略有技巧 可以先做一下hd ...
- HDU 5919 Sequence II 主席树
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5919 Sequence II Time Limit: 9000/4500 MS (Java/Othe ...
最新文章
- 目标反射回波检测算法及其FPGA实现 之一:算法概述
- python十进制转八进制_怎样用python进行二进制,八进制,十进制转换
- A Deep Reinforcement Learning Network for Traffic Light Cycle Control 【论文阅读】
- oracle简写sql,Oracle通过sqlplus编辑sql命令
- 搞硬件,钱少破事多,只能另谋出路!
- phpfpm内存越来越高_硬件集成度越来越高 未来DIY玩法方向已定?
- Cisco TrustSec(理解)
- 联发科天玑800适配鸿蒙系统,联发科天玑800什么水平
- 不占内存的浏览器_4款黑科技办公网站,高效实用,不占内存,高手的必备神器...
- selenium webdriver 右键另存为下载文件(结合robot and autoIt)
- stm32usb转串口驱动_新品推荐:乐扩PCI-E转8口RS-232串口卡 支持短铁片
- whitelist方法_Jsoup学习之Whitelist类
- android封装全局调用的toast_自定义Toast,解决系统Toast存在的问题
- STK 12.5.0发布
- pcm5102a解码芯片音质评测_鱼和熊掌兼得——一台可以换芯片的PCM1794解码评测(上)...
- 如何用BIGEMAP在Arcgis中使用bigemap制作特定比例尺的交通位置图
- 金武彩印机械设备有限公司仓储管理系统设计与实现
- 小学计算机课题研究方案,课题研究方案范文《小学信息技术课堂有效教学的探索》...
- 气传导和骨传导耳机哪个好?简单科普这两种蓝牙耳机
- 电子面单怎么申请-JAVA/PHP
热门文章
- linux系统下的mysqlgt;aborted_MySQL令人头疼的Aborted告警案例分析
- 韩信点兵python源代码_少儿编程|Python小课堂 – 韩信点兵
- xp框架下载官方_斐讯路由器系列「K1-K2-K2P-K2T」-Breed刷入工具v1.1支持XP系统
- 在ue4制作中容易出现哪些问题_青年鸡在育成期容易出现的问题有哪些呢
- webstorm怎么跑项目_怎么跑Mint-UI的实例,你知道吗?
- 世界地图20亿像素_高通骁龙690 5G平台发布,支持1.92亿像素性能提升20%
- THE QUESTIONS :The Top 25 (what we don't know?)
- [CH Round #61] 取数游戏
- 2017年9月9日普级组 优美三角剖分
- python的合法名称_Python未定义名称:turn。!