裸线段树区间合并,题目本身不难,就是细节处理比较麻烦。

因为涉及到异或运算,所以连续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相关推荐

  1. 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变 ...

  2. hdu 3397 Sequence operation(线段树,lazy,区间合并)

    hdu 3397 Sequence operation 线段树lazy和区间合并结合的一个题,相当于几个题集中到一起嘛,分开想就好了 0,1,2操作都要lazy,2的异或操作找到每一只含1或只含0的区 ...

  3. HDU 3397 Sequence operation 线段树 成段更新 区间合并

    比较综合的题. 两个标记  setv,xorr.setv的优先级高于xorr,当一个节点获得一个setv时,他之前的xorr要清除. //#pragma comment(linker, "/ ...

  4. HDU - 3397 Sequence operation(线段树+区间合并)

    题目链接:点击查看 题目大意:给定一个初始的数列,然后依次进行m次操作: 0 a b:将闭区间[a,b]内的点都变为0 1 a b:将闭区间[a,b]内的点都变为1 2 a b:将闭区间[a,b]内的 ...

  5. 【线段树】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 ...

  6. 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 ...

  7. HDU - 5919 Sequence II——主席树+区间种类++逆序建树

    [题目描述] HDU - 5919 Sequence II [题目分析] 题目给定一个数组,每次查询一个区间,找出区间内不同数字的个数x,然后输出按出现顺序第x/2向上取整个数字的位置. 按照要求,我 ...

  8. Sequence operation HDU - 3397

    点击打开链接 写了好久 终于AC 还是对线段树理解不到位 0 1操作是裸区间着色 2操作是裸区间翻转(异或) 对于这两种区间操作各设两个laz变量 3操作是裸区间查询 4操作略有技巧 可以先做一下hd ...

  9. HDU 5919 Sequence II 主席树

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5919 Sequence II Time Limit: 9000/4500 MS (Java/Othe ...

最新文章

  1. 目标反射回波检测算法及其FPGA实现 之一:算法概述
  2. python十进制转八进制_怎样用python进行二进制,八进制,十进制转换
  3. A Deep Reinforcement Learning Network for Traffic Light Cycle Control 【论文阅读】
  4. oracle简写sql,Oracle通过sqlplus编辑sql命令
  5. 搞硬件,钱少破事多,只能另谋出路!
  6. phpfpm内存越来越高_硬件集成度越来越高 未来DIY玩法方向已定?
  7. Cisco TrustSec(理解)
  8. 联发科天玑800适配鸿蒙系统,联发科天玑800什么水平
  9. 不占内存的浏览器_4款黑科技办公网站,高效实用,不占内存,高手的必备神器...
  10. selenium webdriver 右键另存为下载文件(结合robot and autoIt)
  11. stm32usb转串口驱动_新品推荐:乐扩PCI-E转8口RS-232串口卡 支持短铁片
  12. whitelist方法_Jsoup学习之Whitelist类
  13. android封装全局调用的toast_自定义Toast,解决系统Toast存在的问题
  14. STK 12.5.0发布
  15. pcm5102a解码芯片音质评测_鱼和熊掌兼得——一台可以换芯片的PCM1794解码评测(上)...
  16. 如何用BIGEMAP在Arcgis中使用bigemap制作特定比例尺的交通位置图
  17. 金武彩印机械设备有限公司仓储管理系统设计与实现
  18. 小学计算机课题研究方案,课题研究方案范文《小学信息技术课堂有效教学的探索》...
  19. 气传导和骨传导耳机哪个好?简单科普这两种蓝牙耳机
  20. 电子面单怎么申请-JAVA/PHP

热门文章

  1. linux系统下的mysqlgt;aborted_MySQL令人头疼的Aborted告警案例分析
  2. 韩信点兵python源代码_少儿编程|Python小课堂 – 韩信点兵
  3. xp框架下载官方_斐讯路由器系列「K1-K2-K2P-K2T」-Breed刷入工具v1.1支持XP系统
  4. 在ue4制作中容易出现哪些问题_青年鸡在育成期容易出现的问题有哪些呢
  5. webstorm怎么跑项目_怎么跑Mint-UI的实例,你知道吗?
  6. 世界地图20亿像素_高通骁龙690 5G平台发布,支持1.92亿像素性能提升20%
  7. THE QUESTIONS :The Top 25 (what we don't know?)
  8. [CH Round #61] 取数游戏
  9. 2017年9月9日普级组 优美三角剖分
  10. python的合法名称_Python未定义名称:turn。!