Binary Search (n+m)log(10^10) - Faster than 98%
\ntypedef long long ll;\n#define all(nums) nums.begin(), nums.end()\n#define reverse(nums1, nums2) reverse(all(nums1)), reverse(all(nums2))\nclass Solution {\np
```\ntypedef long long ll;\n#define all(nums) nums.begin(), nums.end()\n#define reverse(nums1, nums2) reverse(all(nums1)), reverse(all(nums2))\nclass Solution {\npublic:\n    inline ll count(vector<int> &nums1, vector<int> &nums2, ll limit) {\n        ll result = 0;\n        for(int i = 0, j = nums2.size()-1; i < nums1.size(); i++, result += (j+1))\n            while(j >= 0 && (ll)nums1[i]*nums2[j] > limit) j--;\n        return result;\n    }\n    tuple<ll, ll, ll, vector<int>, vector<int>> getStats(vector<int> nums) {\n        vector<int> pos(upper_bound(all(nums), 0), nums.end()), neg(nums.begin(), lower_bound(all(nums), 0));\n        return {neg.size(), std::count(all(nums), 0), pos.size(), neg, pos};\n    }\n    long long kthSmallestProduct(vector<int>& nums1, vector<int>& nums2, long long k) {\n        ll n = nums1.size(), m = nums2.size();\n        auto [neg1, zero1, pos1, nums1Neg, nums1Pos] = getStats(nums1);\n        auto [neg2, zero2, pos2, nums2Neg, nums2Pos] = getStats(nums2);\n        ll negCount = pos1*neg2+pos2*neg1, zeroCount = n*zero2+m*zero1-zero1*zero2, left=-1e10-5, right=1e10+5, mid;\n        if(k > negCount) {\n            if(k <= negCount+zeroCount) return 0;\n            reverse(nums1Neg, nums2Neg);\n            left = 1;\n            k -= (negCount + zeroCount);\n        } else {\n            reverse(nums1Pos, nums2Pos);\n            right = 0;\n            swap(nums2Pos, nums2Neg);\n        }\n        while(left < right) {\n            mid = left + (right-left)/2;\n            if(count(nums1Pos, nums2Pos, mid) + count(nums2Neg, nums1Neg, mid) < k) left = mid+1;\n            else right = mid;\n        }\n        return left;\n    }\n};\n```
[]