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 }

 

posted @ 2013-05-10 12:50  冰鸮  阅读(260)  评论(2编辑  收藏  举报