FZU 2105 Digits Count(WA)

裸线段树,目前WA中。

如果用离散化的话,就跟 poj 2528 Mayor’s posters 一样中间需要插点,之前样例一直跑不对就是这个原因。

但这个做法依然不对,我这种做法相当于默认为位运算的运算顺序不影响结果,实际上对于位运算来说,混合运算不同的运算顺序不一定得到相同的结果。

 虽然花了很长时间很大功夫也没做出来,但是知道自己错在哪里也是一种收获。

 

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 
  6 #define lson l, m, rt << 1
  7 #define rson m + 1, r, rt << 1 | 1
  8 
  9 using namespace std;
 10 
 11 const int MAXN = 1e6;
 12 const int MAXSIZE = 222222;
 13 const int ANDFLAG = (1 << 16) - 1;
 14 
 15 struct Seg
 16 {
 17     int cnt[16];
 18     int andFlag;
 19     int orFlag;
 20     int xorFlag;
 21     bool first;
 22 };
 23 
 24 struct oper
 25 {
 26     char str[5];
 27     int a, b, val;
 28 };
 29 
 30 int N, Q;
 31 Seg ss[ MAXSIZE << 2 ];
 32 oper op[ MAXSIZE];
 33 int num[MAXN];
 34 int X[MAXSIZE << 2];
 35 
 36 void PushUp( int rt )
 37 {
 38     int lc = rt << 1;
 39     int rc = rt << 1 | 1;
 40     for ( int i = 0; i < 16; ++i )
 41         ss[rt].cnt[i] = ss[lc].cnt[i] + ss[rc].cnt[i];
 42     return;
 43 }
 44 
 45 void change( int c, int val, int *nn )
 46 {
 47     int temp[16] = { 0 };
 48 
 49     for ( int i = 0; i < 16; ++i )
 50     {
 51         int tp = i;
 52         if ( c == 1 ) tp &= val;
 53         else if ( c == 3 ) tp ^= val;
 54         else if ( c == 2 ) tp |= val;
 55      //   printf( "pre nn[%d]=%d tp=%d\n", i, nn[i], tp );
 56         temp[tp] += nn[i];
 57     }
 58 
 59     for ( int i = 0; i < 16; ++i )
 60     {
 61       //  printf("nn[%d] = %d\n", i, nn[i] );
 62         nn[i] = temp[i];
 63     }
 64 
 65     return;
 66 }
 67 
 68 void PushDown( int rt )
 69 {
 70     int lc = rt << 1;
 71     int rc = rt << 1 | 1;
 72 
 73     if ( ss[rt].andFlag != ANDFLAG )
 74     {
 75         ss[lc].andFlag = ss[rc].andFlag = ss[rt].andFlag;
 76         change( 1, ss[rt].andFlag, ss[rt].cnt );
 77         ss[rt].andFlag = ANDFLAG;
 78     }
 79 
 80     if ( ss[rt].first == false )
 81     {
 82         ss[lc].first = ss[rc].first = ss[rt].first;
 83         ss[lc].xorFlag = ss[rc].xorFlag = ss[rt].xorFlag;
 84         change( 3, ss[rt].xorFlag, ss[rt].cnt );
 85 
 86         ss[rt].first = true;
 87         ss[rt].xorFlag = 0;
 88     }
 89 
 90     if ( ss[rt].orFlag != 0 )
 91     {
 92         ss[lc].orFlag = ss[rc].orFlag = ss[rt].orFlag;
 93         change( 2, ss[rt].orFlag, ss[rt].cnt );
 94         ss[rt].orFlag = 0;
 95     }
 96 
 97     return;
 98 }
 99 
100 int query( int L, int R, int l, int r, int rt )
101 {
102     if ( L <= l && r <= R )
103     {
104         PushDown(rt);
105         //printf( "(%d, %d)\n", l, r );
106         int sum = 0;
107 
108         //printf("query(%d, %d)\n", l, r);
109         for ( int i = 0; i < 16; ++i )
110         {
111           //  printf( "%d %d\n", i, ss[rt].cnt[i] );
112             sum += i * ss[rt].cnt[i];
113         }
114 
115         return sum;
116     }
117 
118     PushDown( rt );
119     int m = ( l + r ) >> 1;
120 
121     int tpL = 0, tpR = 0;
122     if ( L <= m ) tpL = query( L, R, lson );
123     if ( R > m ) tpR = query( L, R, rson );
124 
125     PushUp(rt);
126 
127    // printf( "(%d, %d)=%d\n", l, r, tpL + tpR );
128     return tpL + tpR;
129 }
130 
131 void Update( int L, int c, int l, int r, int rt )   //插点
132 {
133     if ( L == l && L == r )
134     {
135         ++ss[rt].cnt[c];
136         return;
137     }
138 
139     int m = ( l + r ) >> 1;
140     if ( L <= m ) Update( L, c, lson );
141     else Update( L, c, rson );
142 
143     PushUp( rt );
144     return;
145 }
146 
147 void UpdateFlag( int L, int R, int c, int val, int l, int r, int rt ) //操作
148 {
149     if ( L <= l && r <= R )
150     {
151         if ( c == 1 )               //与操作
152             ss[rt].andFlag &= val;
153         else if ( c == 2 )          //或操作
154             ss[rt].orFlag |= val;
155         else                        //异或操作
156         {
157             if ( ss[rt].first )
158             {
159                 ss[rt].first = false;
160                 ss[rt].xorFlag = val;
161             }
162             else ss[rt].xorFlag ^= val;
163         }
164         PushDown(rt);
165 
166        // printf( "update(%d, %d)\n", l, r );
167         //for ( int i = 0; i < 16; ++i )
168        // {
169          //   printf( "%d %d\n", i, ss[rt].cnt[i] );
170           //  sum += i * ss[rt].cnt[i];
171         //}
172 
173         return;
174     }
175 
176     PushDown(rt);
177     int m = ( l + r ) >> 1;
178     if ( L <= m ) UpdateFlag( L, R, c, val, lson );
179     if ( R > m )  UpdateFlag( L, R, c, val, rson );
180     PushUp(rt);
181 
182     return;
183 }
184 
185 void build( int l, int r, int rt )   //建树初始化
186 {
187     memset( ss[rt].cnt, 0, sizeof(ss[rt].cnt));
188     ss[rt].andFlag = ANDFLAG;
189     ss[rt].orFlag = 0;
190     ss[rt].first = true;
191     ss[rt].xorFlag = 0;
192 
193     if ( l == r ) return;
194 
195     int m = ( l + r ) >> 1;
196     build( lson );
197     build( rson );
198 
199     return;
200 }
201 
202 int BinSearch( int *nn, int tar, int x, int y )  //二分查找
203 {
204     int mid;
205     while ( x < y )
206     {
207         mid = ( x + y ) >> 1;
208         if ( nn[mid] == tar ) return mid;
209         if ( nn[mid] > tar ) y = mid - 1;
210         else x = mid + 1;
211     }
212     return x;
213 }
214 
215 int main()
216 {
217     int T;
218   //  freopen( "s.out", "w", stdout );
219     scanf( "%d", &T );
220     while ( T-- )
221     {
222         scanf( "%d%d", &N, &Q );
223         for ( int i = 0; i < N; ++i )    //保存每个数
224             scanf( "%d", &num[i] );
225 
226         int nn = 0;
227         for ( int i = 0; i < Q; ++i )   //保存
228         {
229             int a, b, val;
230             scanf( "%s", op[i].str );
231             if ( op[i].str[0] == 'S' ) scanf( "%d%d", &a, &b );
232             else scanf( "%d%d%d", &val, &a, &b );
233 
234             op[i].a = a;
235             op[i].b = b;
236             op[i].val = val;
237 
238             X[ nn++ ] = a;
239             X[ nn++ ] = b;
240         }
241         sort( X, X + nn );
242         int m = 1;
243 
244         for ( int i = 1; i < nn; ++i )   //去除重点
245             if ( X[i] != X[i - 1] ) X[ m++ ] = X[i];
246 
247         for ( int i = m - 1; i > 0; --i )   //加点
248             if ( X[i] != X[i - 1] + 1 )
249                 X[m++] = X[i - 1] + 1;
250 
251         sort( X, X + m );
252 /*
253         for ( int i = 0; i < m; ++i ) printf( "%d ", X[i] );
254         puts("");
255 */
256         build( 0, m, 1 );    //建树
257         for ( int i = 0; i < N; ++i )   //插点
258         {
259             int addr = BinSearch( X, i, 0, m );
260           //  printf("addr = %d\n", addr );
261             Update( addr, num[i], 0, m, 1 );
262         }
263 
264         for ( int i = 0; i < Q; ++i )
265         {
266             int a = BinSearch( X, op[i].a , 0, m );
267             int b = BinSearch( X, op[i].b , 0, m );
268 
269             if ( op[i].str[0] == 'A' ) UpdateFlag( a, b, 1, op[i].val, 0, m, 1 );
270             else if ( op[i].str[0] == 'O' )
271             {
272            //     printf("(%d, %d)\n", a, b );
273                 UpdateFlag( a, b, 2, op[i].val, 0, m, 1 );
274             }
275             else if ( op[i].str[0] == 'X' ) UpdateFlag( a, b, 3, op[i].val, 0, m, 1 );
276             else printf("%d\n", query( a, b, 0, m, 1 ) );
277            // puts("");
278         }
279     }
280     return 0;
281 }

 

posted @ 2013-05-09 23:23  冰鸮  阅读(377)  评论(6编辑  收藏  举报