HDU 3397 Sequence operation
生活随笔
收集整理的這篇文章主要介紹了
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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS PUSH功能图文教程链接
- 下一篇: 比传统菜单更为方便的系统菜单模式-Spr