• 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 }
  • 相关阅读:
    word2vec层次化softmax理解
    python动态加载模块,并获取模块中的类与方法(类似反射)
    用Python装饰器给函数自动加上try except
    3D打印第二弹:狗牌
    【高等代数】06
    【高等代数】05
    沙箱-guacamole
    关于写博客的一点思考
    二阶段目标检测总结
    Waymo object detect 2D解决方案论文拓展
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3089504.html
Copyright © 2020-2023  润新知