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 }

 

你可能感兴趣的:(count)