C# Solution - Binary Search with Counting
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n\n# Complexity\n- Time 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity:\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\npublic class Solution {\n    private void Parition(int[] nums1, int[] nums2, out int posLen1, out int negLen1, out int posLen2, out int negLen2, \n        out int[] pos1, out int[] neg1, out int[] pos2, out int[] neg2, out bool isResultPositive, ref long k)\n    {\n        posLen1 = 0; negLen1 = 0; posLen2 = 0; negLen2 = 0;\n\n        foreach (int num in nums1)\n        {\n            if (num < 0) negLen1++;\n            else posLen1++;\n        }\n\n        foreach (int num in nums2)\n        {\n            if (num < 0) negLen2++;\n            else posLen2++;\n        }\n\n        int numNegatives = posLen1 * negLen2 + posLen2 * negLen1;\n        isResultPositive = k > numNegatives;\n\n        pos1 = new int[posLen1]; neg1 = new int[negLen1];\n        pos2 = new int[posLen2]; neg2 = new int[negLen2];\n\n        int iPos = 0, iNeg = 0;\n        foreach (int num in nums1)\n        {\n            if (num < 0)\n                neg1[iNeg++] = num;\n            else \n                pos1[iPos++] = num;\n        }\n\n        iPos = 0; iNeg = 0;\n        foreach (int num in nums2)\n        {\n            if (num < 0)\n                neg2[iNeg++] = num;\n            else \n                pos2[iPos++] = num;\n        }\n        \n        // if result is positive, we want negative numbers is descending order.\n        // if result is positive, we want negative numbers is ascending order.\n        // Reason is - for two arrays, if we keep i at arr1[0] and j and arr2[n-1], by \n        // comparing both values, we should be able to say that left side elements in arr2\n        // are less than arr1[i] * arr2[j]\n        if (isResultPositive)\n        {\n            k -= numNegatives; // find (k - numNeg)th positive number\n            Array.Reverse(neg1);\n            Array.Reverse(neg2);\n        }\n        else\n        {\n            Array.Reverse(pos1);\n            Array.Reverse(pos2);\n        }\n    }\n\n    private long GetValidNumberCount(int[] arr1, int[] arr2, long val)\n    {\n        int i = 0, j = arr2.Length-1;\n        long count = 0L;\n\n        while (i < arr1.Length && j >= 0)\n        {\n            // all numbers of left of j are less than val\n            if (((long)arr1[i] * (long)arr2[j]) <= val)\n            {\n                count += (long)(j+1);\n                i++;\n            }\n            else\n            {\n                j--;\n            }\n        }\n\n        return count;\n    }\n\n\n    public long KthSmallestProduct(int[] nums1, int[] nums2, long k) \n    {\n\n        Parition(nums1, nums2, out int posLen1, out int negLen1, out int posLen2, out int negLen2, out int[] pos1, \n                    out int[] neg1, out int[] pos2, out int[] neg2, out bool isResultPositive, ref k);\n        \n        // high , low based on input constraints\n        long low = -(long)Math.Pow(10, 10) - 1;\n        long high =  (long)Math.Pow(10, 10) + 1;\n\n        while (low < high)\n        {\n            long mid = low + (high - low)/2;\n            long count = isResultPositive ? GetValidNumberCount(pos1, pos2, mid) + GetValidNumberCount(neg1, neg2, mid)\n                : GetValidNumberCount(pos1, neg2, mid) + GetValidNumberCount(pos2, neg1, mid);\n            \n            if (count >= k)\n            {\n                high = mid;\n            }\n            else\n            {\n                low = mid + 1;\n            }\n        }\n\n        return high;\n    }\n}\n```
['C#']