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 }

 

你可能感兴趣的:(count)