class Solution {
public:

    int OR(int i, int j, vector<vector<int>> &prefix)
    {
        int k = 0;

        for (int u = 0; u <= 30; u++)
        {
            int one;
            if (i == 0)
                one = prefix[u][j];
            else
                one = prefix[u][j] - prefix[u][i - 1];

            if (one >= 1)
            {
                k = k + (1 << u);
            }
        }

        return k;
    }

    int minimumSubarrayLength(vector<int>& nums, int k)
    {
        int n = nums.size();

        vector<vector<int>> bit(31, vector<int>(n));

        for (int j = 30; j >= 0; j--)
        {
            for (int i = 0; i < n; i++)
            {
                bit[j][i] = (nums[i] >> j) & 1;
            }
        }

        vector<vector<int>> prefix(31, vector<int>(n));

        for (int j = 30; j >= 0; j--)
        {
            for (int i = 0; i < n; i++)
            {
                if (i == 0)
                    prefix[j][i] = bit[j][i];
                else
                    prefix[j][i] = prefix[j][i - 1] + bit[j][i];
            }
        }
        
        // from here the exact previous Concept Building optimization code of two pointer template is added 
        // one thing above whole condition bitwise OR condition is added extra with respect to question the two pointer template is exact it is 

        // 'i' pointer we rename the variable it as left 
        // 'j' pointer we rename the variable it as right 
        
        int minLength = INT_MAX;
        int windowSum = 0;
        int left = 0;

        for (int right = 0; right < n; ++right)
        {
            windowSum = OR(left, right, prefix);

            while (windowSum >= k && left <= right)
            {
                // in the whole algorithm this loop will only go from left = 0 till left = n-1
                // so only total O(N) extra operations.

                minLength = min(minLength, right - left + 1);

                windowSum = OR(left + 1, right, prefix);
                ++left;
            }

            if (left <= right)
            {

            }
            else
            {
                right = left;
            }
        }

        if (minLength == INT_MAX)
        {
            return -1;
        }

        return minLength;
    }
};