inlinevoidinsert(int x){ if (d[x]) return; d[x] = 1; for (registerint i = 1; i <= 7; i++, x >>= 3) val[i][x >> 3] |= 1 << (x & 7); }
删除
与插入没什么区别,直接把压位中的操作换成 xor 就好了。
1 2 3 4 5
inlinevoiderase(int x){ if (d[x]) d[x] = 0; elsereturn; for (registerint i = 1; i <= 7; i++, x >>= 3) if (val[i][x >> 3] ^= 1 << (x & 7)) return; }
最值
从最底下往上跳,沿最左/最有非空子树跳回根就好了。
1 2 3 4 5 6 7 8 9 10 11 12 13
inlineintgetMin(){ if (!val[7][0]) return-1; registerint p = lbound[val[7][0]]; for (registerint i = 6; i; i--) p = (p << 3) + lbound[val[i][p]]; return p; }
inlineintgetMax(){ if (!val[7][0]) return-1; registerint p = rbound[val[7][0]]; for (registerint i = 6; i; i--) p = (p << 3) + rbound[val[i][p]]; return p; }
bool d[2097154]; unsignedchar val[8][1000001 + 1]; int lbound[256 + 1], rbound[256 + 1]; int lc[8], rc[8];
inlinevoidinsert(int x){ if (d[x]) return; d[x] = 1; for (registerint i = 1; i <= 7; i++, x >>= 3) val[i][x >> 3] |= 1 << (x & 7); }
inlinevoiderase(int x){ if (d[x]) d[x] = 0; elsereturn; for (registerint i = 1; i <= 7; i++, x >>= 3) if (val[i][x >> 3] ^= 1 << (x & 7)) return; }
inlineintgetMin(){ if (!val[7][0]) return-1; registerint p = lbound[val[7][0]]; for (registerint i = 6; i; i--) p = (p << 3) + lbound[val[i][p]]; return p; }
inlineintgetMax(){ if (!val[7][0]) return-1; registerint p = rbound[val[7][0]]; for (registerint i = 6; i; i--) p = (p << 3) + rbound[val[i][p]]; return p; }
inlineintprecursor(int p){ if (!val[7][0]) return-1; registerint s = val[1][p >> 3] & lc[p & 7]; if (s) return (p ^ (p & 7)) | rbound[s]; for (registerint i = 2; i <= 7; i++) { p >>= 3; s = val[i][p >> 3] & lc[p & 7]; if (s) { p = (p ^ (p & 7)) | rbound[s]; for (registerint j = i - 1; j; j--) p = (p << 3) | rbound[val[j][p]]; return p; } } return-1; }
inlineintsuccessor(int p){ if (!val[7][0]) return-1; registerint s = val[1][p >> 3] & rc[p & 7]; if (s) return (p ^ (p & 7)) | lbound[s]; for (registerint i = 2; i <= 7; i++) { p >>= 3; s = val[i][p >> 3] & rc[p & 7]; if (s) { p = (p ^ (p & 7)) | lbound[s]; for (registerint j = i - 1; j; j--) p = (p << 3) | lbound[val[j][p]]; return p; } } return-1; }
int n, m, a, b;
intmain(){ // freopen("in.in", "r", stdin); for (registerint i = 1; i < 256; i++) { registerint j = 0; while (!(i & 1 << j)) j++; lbound[i] = j; j = 7; while (!(i & 1 << j)) j--; rbound[i] = j; } for (registerint i = 0; i < 8; i++) lc[i] = 255 >> 8 - i, rc[i] = 255 & (255 << i + 1); read(n), read(m); for (int i = 0; i < m; i++) { read(a); if (a < 3) { read(b); if (a == 1) insert(b); elseif (a == 2) erase(b); } elseif (a > 4) { read(b); if (a == 5) print(precursor(b)), print('\n'); elseif (a == 6) print(successor(b)), print('\n'); elseif (a == 7) print(d[b] && val[1][b >> 3] & 1 << (b & 7) ? 1 : -1), print('\n'); } elseif (a == 3) { print(getMin()), print('\n'); } elseif (a == 4) { print(getMax()), print('\n'); } } flush(); return0; }