Блог пользователя not_wiz

Автор not_wiz, история, 2 года назад, По-английски

In problems involving bit masking, sometimes you might need to generate all submasks for a given mask.

Mask is nothing but a specific pattern of bits you use for some desired operation. For eg. to turn on 4th bit(0 based indexing) of a given number, you can use the mask 10000 (16 in decimal) and OR with the given number.

Submask of a given mask is nothing but a mask whose set bits are a subset of the given mask. For eg., 1010, 1000, 0010 are submasks of 1011, while 1100 is not a submask.

Now our problem is to generate all submasks for a given mask. We can solve this problem easily using recursion generating all submasks, but there’s a concise and elegant way of doing the same. We will discuss that here.

Consider the mask 10110 (22 in decimal). All the submasks of the given mask are 10110, 10100, 10010, 00110, 10000, 00100, 00010 and 00000.

We know that subtracting 1 from a given number unsets the rightmost set bit and sets all the unset bits after it.

For eg. 12 in binary is 1100, now when we subtract 1 from it, we get 11 (1011 in binary). Consider another example as 20 (10100). On subtracting 1, we get 19 (10011).

We can exploit this behavior to solve our problem of generating all submasks. If we subtract 1 from our mask and then AND with the original mask, we will end up with a submask with it’s rightmost set bit unset. Continuing our example of 10110 (22 in decimal), after subtracting 1, we will get 10101 and ANDing it with original mask 10110, we get 10100 which is one of the required submask. We keep on doing the same operation until we end up with 0.

If you didn’t understand, give it a dry run generating all 8 submasks and you will get it.

Here’s the simple code.

I learnt this simple yet surprising technique from a random leetcode article and felt worth sharing.

  • Проголосовать: нравится
  • +50
  • Проголосовать: не нравится

»
2 года назад, # |
  Проголосовать: нравится -31 Проголосовать: не нравится

https://atcoder.jp/contests/abc269/tasks/abc269_c — A problem where this can be used has appeared on ABC269.

»
2 года назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится
»
2 года назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

Thanks man . Great article!!