lundi 25 janvier 2021

Finding odd divisors with bit-shifting

(This question refers to this Codeforces problem) I want to find out if any n (2 ≤ n ≤ 10¹⁴) has an odd divisor or not. Using C++11, I thought it would be possible to brute force a solution by iterating through every odd number until n, and checking with % if it is divisible or not. Something such as:

for(unsigned long long i=3;i<n;i+=2){
   if(n%i==0) return true; //It has an odd divisor
}
return false; //n%j==0 was never true so it doesn't have an odd divisor

Which of course turned out to be extremely slow if any big number were given. I found out people were solving it by bit-shifting it, and checking if the last bit was 1, something similar to this:

while(!(n&1))n>>=1;
if(n==1) return false; else return true;

If I am not mistaken, this last piece of code is checking if it's odd with the last bit (n&1) by performing n=n/2ⁿ. How does computing n=n/2ⁿ have the same accuracy in regards solving the problem as checking it for every odd number? (How do I know that I am not ''skipping'' a divisor?).

Aucun commentaire:

Enregistrer un commentaire