Monday 2 September 2013

RANGE OPERATION


/*
    *  Let us define A(m, n) = m & (m+1) & ... & (n-1) & n, where & is the bitwise AND operation.
    *  Write a program that, given 64-bit unsigned longs m and n, computes A(m, n).
    *  Example Inputs:
    *  49 54
    *  2 2
    *  2 3
    *  Outputs (respectively):
    *  48
    *  2
    *  2
    *  Explanation:
    *  A(49, 54) = 49 & 50 & 51 & 52 & 53 & 54 = 48
    *  A(2, 2) = 2. If m = n, A(m, n) = m = n.
    *  A(2, 3) = 2 & 3 = 2
    *  3
    *  Solution Guidance:
    *  Let k be the bit width (maximum number of bits) of the primitive.
    *  Easy: O(n - m) time. Consider that since m and n can be any 64-bit numbers, this could be
    *  huge.
    *  Moderate-Hard: O(k) time.
    *  Hard: O(log(k)) time.
*/
 
#include <iostream>
using namespace std;
 
int RangeOperationEASY(long long int m,long long int n)
{
    long long int result = n;
    n--;
    for(;n>=m; n--)
    {
        result &= n;
    }
    return result;
}
 
long long int getNextHighestPower(long long int diff)
{
    long long int pow = 0;
    while(true)
    {
        if(diff > (1<<pow))
            pow++;
        else
            return pow;
    }
}
 
long long int getNextHighestPowerlogn(long long int diff)
{
    diff--;
    diff |= diff >> 1;
    diff |= diff >> 2;
    diff |= diff >> 4;
    diff |= diff >> 8;
    diff |= diff >> 16;
    diff |= diff >> 32;
    diff++;
    return diff;
}
 
long long int RangeOperationHARD(long long int m, long long int n)
{
    long long int result = m & n;
    long long int diff = n-m+1;
    long long int mask = ~(getNextHighestPowerlogn(diff)-1);
    return result & mask;
}
 
int main()
{  
    long long int m;
    long long int n;
    int testCases;
    cin>>testCases;
    for(int i=0; i<testCases; i++)
    {
        cin>>m>>n;
        cout<<"\nEASY : "<<RangeOperationEASY(m,n);
        cout<<"\nHARD : "<<RangeOperationHARD(m,n)<<endl;
    }
}

No comments:

Post a Comment