zoukankan      html  css  js  c++  java
  • FZU 2105 Digits Count(AC)

    因为0-15二进制下最大是1111,所以可以每个区间记录一下各个位上1的个数,这样不管是对于操作也好还是求和也好都简便了许多。

    PS1.感谢薛神提点。

    PS2.注意细节

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 
      5 #define lson l, m, rt << 1
      6 #define rson m + 1, r, rt << 1 | 1
      7 
      8 const int MAXN = 1000002;
      9 
     10 int cnt[ MAXN << 2 ][4];
     11 int flag[ MAXN << 2 ][4];
     12 int Xor[ MAXN << 2 ][4];   //标记该位是否需要异或
     13 
     14 int N, Q;
     15 
     16 void PushUp( int rt )
     17 {
     18     int lc = rt << 1;
     19     int rc = rt << 1 | 1;
     20     for ( int i = 0; i < 4; ++i )
     21         cnt[rt][i] = cnt[lc][i] + cnt[rc][i];
     22     return;
     23 }
     24 
     25 void PushDown( int rt, int m, int l, int r )
     26 {
     27     int lc = rt << 1;
     28     int rc = rt << 1 | 1;
     29     for ( int i = 0; i < 4; ++i )
     30     {
     31         if ( flag[rt][i] != -1 )
     32         {
     33             flag[lc][i] = flag[rc][i] = flag[rt][i];
     34             cnt[lc][i] = flag[lc][i] * ( m - l + 1 );
     35             cnt[rc][i] = flag[rc][i] * ( r - m );
     36             flag[rt][i] = -1;
     37             Xor[lc][i] = Xor[rc][i] = 0;
     38         }
     39         else if ( Xor[rt][i] )
     40         {
     41             cnt[lc][i] = m - l + 1 - cnt[lc][i];
     42             cnt[rc][i] = r - m - cnt[rc][i];
     43 
     44             if ( flag[lc][i] != -1 ) flag[lc][i] ^= 1;
     45             else Xor[lc][i] ^= 1;
     46 
     47             if ( flag[rc][i] != -1 ) flag[rc][i] ^= 1;
     48             else Xor[rc][i] ^= 1;
     49 
     50             Xor[rt][i] = 0;
     51         }
     52     }
     53 }
     54 
     55 int Query( int L, int R, int l, int r, int rt )
     56 {
     57     if ( L <= l && r <= R )
     58     {
     59         int sum = 0;
     60         for ( int i = 0; i < 4; ++i )
     61         {
     62             sum += ( 1 << i ) * cnt[rt][i];
     63        //     printf( "cnt[%d]=%d\n", i, cnt[rt][i] );
     64         }
     65         return sum;
     66     }
     67 
     68     int m = ( l + r ) >> 1;
     69     int ret = 0;
     70 
     71     PushDown( rt, m, l, r );
     72 
     73     if ( L <= m ) ret += Query( L, R, lson );
     74     if ( R > m )  ret += Query( L, R, rson );
     75 
     76     PushUp( rt );
     77     return ret;
     78 }
     79 
     80 void AND( int rt, int l, int r, int opn )
     81 {
     82     for ( int i = 0; i < 4; ++i )
     83     {
     84         if ( ( 1 << i ) & opn ) continue;
     85         flag[rt][i] = 0;
     86         cnt[rt][i] = 0;
     87         Xor[rt][i] = 0;
     88     }
     89     return;
     90 }
     91 
     92 void OR( int rt, int l, int r, int opn )
     93 {
     94     for ( int i = 0; i < 4; ++i )
     95     {
     96         if ( !( (1 << i) & opn ) ) continue;
     97         flag[rt][i] = 1;
     98         cnt[rt][i] = r - l + 1;
     99         Xor[rt][i] = 0;
    100     }
    101     return;
    102 }
    103 
    104 void XOR( int rt, int l, int r, int opn )
    105 {
    106     for ( int i = 0; i < 4; ++i )
    107     {
    108         if ( !( ( 1 << i ) & opn ) ) continue;
    109         cnt[rt][i] = r - l + 1 - cnt[rt][i];
    110       //  printf( "**cnt[%d]=%d\n", i, cnt[rt][i] );
    111         if ( flag[rt][i] != -1 ) flag[rt][i] ^= 1;
    112         else Xor[rt][i] ^= 1;
    113     }
    114     return;
    115 }
    116 
    117 void Update( int L, int R, int c, int opn, int l, int r, int rt )
    118 {
    119     if ( L <= l && r <= R )
    120     {
    121         if ( c == 1 ) AND( rt, l, r, opn );
    122         else if ( c == 2 ) OR( rt, l, r, opn );
    123         else XOR( rt, l, r, opn );
    124 
    125         return;
    126     }
    127     int m = ( l + r ) >> 1;
    128     PushDown( rt, m, l, r );
    129 
    130     if ( L <= m ) Update( L, R, c, opn, lson );
    131     if ( R > m ) Update( L, R, c, opn, rson );
    132     PushUp( rt );
    133     return;
    134 }
    135 
    136 void build( int l, int r, int rt )
    137 {
    138     for ( int i = 0; i < 4; ++i )
    139     {
    140         flag[rt][i] = -1;
    141         Xor[rt][i] = 0;
    142     }
    143 
    144     if ( l == r )
    145     {
    146         int a;
    147         scanf( "%d", &a );
    148         for( int i = 0; i < 4; ++i )
    149             if ( a & ( 1 << i ) ) cnt[rt][i] = 1;
    150             else cnt[rt][i] = 0;
    151         return;
    152     }
    153     int m = ( l + r ) >> 1;
    154     build( lson );
    155     build( rson );
    156     PushUp( rt );
    157     return;
    158 }
    159 
    160 int main()
    161 {
    162   //  freopen( "s.out", "w", stdout );
    163     int T;
    164     scanf( "%d", &T );
    165     while ( T-- )
    166     {
    167         scanf( "%d%d", &N, &Q );
    168         build( 0, N - 1, 1 );
    169         while ( Q-- )
    170         {
    171             int a, b, opn;
    172             char str[6];
    173             scanf( "%s", str );
    174             if ( str[0] == 'S' )
    175             {
    176                 scanf( "%d%d", &a, &b );
    177                 printf( "%d\n", Query( a, b, 0, N - 1, 1 ) );
    178             }
    179             else
    180             {
    181                 scanf("%d%d%d", &opn, &a, &b );
    182                 if ( str[0] == 'A' ) Update( a, b, 1, opn, 0, N - 1, 1 );
    183                 else if ( str[0] == 'O' ) Update( a, b, 2, opn, 0, N - 1, 1 );
    184                 else Update( a, b, 3, opn, 0, N - 1, 1 );
    185             }
    186         }
    187     }
    188     return 0;
    189 }
  • 相关阅读:
    notification(浏览器通知)
    面试的信心来源于过硬的基础
    碰撞检测
    使用自定义的鼠标图标 --- cursor url
    js中json字符串转成js对象
    【php学习】字符串操作
    Car的旅行路线(codevs 1041)
    Find them, Catch them(poj 1703)
    Period(poj 1961)
    Power Strings(poj 2406)
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3070934.html
Copyright © 2011-2022 走看看