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

Автор Quake, история, 9 лет назад, По-английски

Hey guys, I was looking at solution to the problem BITS: http://mirror.codeforces.com/contest/484/problem/A . I found a line of code i couldn't understand: for(ll i = x ; i <= y ; i += ( ~ i& -~ i)) ans = i;

what does ( ~ i & -~ i ) do ?

Thank You

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

»
9 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Hi :) updation in the for loop :Like i+=(~i&(-(~i)) will give you "next power of 2 minus 1"number.Like from i=(L=2) to let 100000. It will give you 3,7,15,31,63,127 and so....till (<=100000).So every time in loop we will be storing that i.And at end reporting that last stored i.But I wonder how people come up with these kind of things in contests ??

  • »
    »
    9 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Great Idea, it will not always work properly for the first number, suppose (i=4) the first time this formula will give 5 then the rest is correct. I used this (1LL << (cntBits(i)+1))-1 :D

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

      Thanks you for pointing out the error.And helping me to improve :) .But I don't understand why everybody using this formula.I mean If it is wrong than there must be counter test cases or trillions of hacks.Don't you think.

      • »
        »
        »
        »
        9 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        I think they are sure that i will be (2^k)-1 for any number k so it will work properly for this case.

  • »
    »
    9 лет назад, # ^ |
      Проголосовать: нравится +16 Проголосовать: не нравится

    As was pointed out, this only happens to work if you start with 2. If you want to know exactly what that line does, let's take a sample sequence, starting with 36:

    36, 37, 39, 47, 63, 127

    Does that mean anything to you? No? What if I write it in binary?

    100100, 100101, 100111, 101111, 111111, 1111111

    Can you see what's happening now?

    • »
      »
      »
      9 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      ffao Would you mind telling me that how do you guys up with these kind of expression during a contest in which this is the easiest problem (Div1 A).I mean to say that is this any standard hack that i don't know or you guys build it by your own at that time.

      • »
        »
        »
        »
        9 лет назад, # ^ |
          Проголосовать: нравится +8 Проголосовать: не нравится

        I guess that it is partially both.

        The most difficult part is (x&-x). It extracts least significant 1 from x. If negative numbers are represented using two's complement, then -x = (~x)+1. x&(~x)=0 but adding 1 clears lowest block of 1 and sets lowest 1 in ~x which was lowest 0 in x.

        Knowing that (x & -x) extracts lowest 1, it is easy to come up with rest of the expression during contest.

        (x&-x) extracts lowest 1

        (~x&-~x) extracts lowest 0

        x += (~x&-~x) sets lowest 0 to 1

        There is an easier way to set lowest 0 to 1 which doesn't rely how language or cpu represents negative numbers. x |= (x+1) also sets lowest 0 to 1.