Python optimized long arithmetics (beats 96%)
Intuition\nLet Product=L\cdot(L+1)\cdot...\cdot R.\nWhen the Product is small, we can handle it easily.\nOtherwise, the problems of finding first digits, last d
# Intuition\nLet $$Product=L\\cdot(L+1)\\cdot...\\cdot R$$.\nWhen the $$Product$$ is small, we can handle it easily.\nOtherwise, the problems of finding first digits, last digits and zeros count are solved independently.\n\n# Approach\n\n\n1. Represent the $$Product$$ in exponential form:\n$$Product=\\overline{a_1,a_2a_3a_4a_5a_6a_7...}\\cdot 10^p=M\\cdot 10^p$$,\nwhere $$a_i$$ is $$i$$-th digit from left,\n$$M$$ - mantissa, the fractional part of the base-10 logarithm ($$1\\leq M<10$$):\n$$log_{10}Product=log_{10}M+p$$\n$$\\{log_{10}Product\\}=log_{10}M$$\n$$10^{\\{log_{10}Product\\}}=M$$\n    ##### So we can find the first digits from mantissa:\n    $$\\overline{a_1,a_2a_3a_4a_5a_6a_7...}=M$$\n$$\\overline{a_1a_2a_3a_4a_5,a_6a_7...}=M\\cdot10^4$$\n$$\\overline{a_1a_2a_3a_4a_5}=\u230AM\\cdot10^4\u230B$$\n\n    Because \n$$log_{10}M=\\{log_{10}Product\\}=\\{log_{10}(L\\cdot(L+1)\\cdot...\\cdot R)\\}=\\{ \\sum_{i=L}^{R} log_{10}i\\}$$,\n    ##### we can get a cumulative floating point error due to calling the logarithm function many times.\n    So it is better to minimize the number of calls to the logarithm function.\n    Using Python long arithmetic you need to call the logarithm function only once.\n    Second approach is keeping product of numbers on a segment ($$bufferProduct$$ in code) and calling the logarithm function when the product becomes greater than the threshold ($$maxBufferValue$$ in code).\n    I got AC with $$maxBufferValue=10^{1200}$$.\n\n1. We can find the last digits using modulo operation:\n$$LastNdigits=Product  \\% 10^N$$\n\n1. Trailing zeros count is $$min(pow_2, pow_5)$$,     where $$pow_2$$ and $$pow_5$$ are powers of 2 and 5 respectively from prime factorization of $$Product$$.\n \n\n# Complexity\n- Time complexity\n$$O(n)$$\n\n- Space complexity:\n$$O(n)$$\n\n# Code\n``` Python_call_log10_with_threshold []\n# Runtime: 343ms, beats 96.15% of users with Python3\n# Memory Usage: 16.83MB, beats 40.38% of users with Python3\n\nclass Solution:\n    def abbreviateProduct(self, left: int, right: int) -> str:        \n        last = 1\n        modulo = 10 ** 5\n\n        twosCount = 0\n        fivesCount = 0\n\n        sumLog10 = 0\n        maxBufferValue = 10 ** 1200\n        bufferProduct = 1\n        \n        for x in range(left, right + 1):\n            bufferProduct *= x\n\n            if bufferProduct > maxBufferValue:\n                sumLog10 += math.log10(bufferProduct)\n                bufferProduct = 1\n\n            while x % 2 == 0:\n                twosCount += 1\n                x //= 2\n                \n            while x % 5 == 0:\n                fivesCount += 1\n                x //= 5\n            \n            last = (last * x) % modulo        \n\n        sumLog10 += math.log10(bufferProduct)\n        zerosCount = min(twosCount, fivesCount)\n\n        if sumLog10 < 10 + zerosCount:\n            productString = str(bufferProduct)\n            return productString[:len(productString) - zerosCount] + \'e\' + str(zerosCount)\n        \n        twosCount -= zerosCount\n        fivesCount -= zerosCount        \n        \n        last = (last * pow(2, twosCount, modulo)) % modulo\n        last = (last * pow(5, fivesCount, modulo)) % modulo\n        \n        first = int(pow(10, sumLog10 % 1 + 4.0))\n       \n        return str(first) + \'...\' + str(last).zfill(5) + \'e\' + str(zerosCount) \n        \n```\n``` Python_single_log10_call []\n# Runtime: 6085 ms, beats 19.23% of users with Python3\n# Memory Usage: 16.80 MB, beats 40.38% of users with Python3\n\nclass Solution:\n    def abbreviateProduct(self, left: int, right: int) -> str:   \n        modulo = 10 ** 5\n        product = 1\n\n        for i in range(left, right + 1):\n            product *= i\n\n        zerosCount = 0\n\n        while product % 10 == 0:\n            product //= 10\n            zerosCount += 1\n        \n        prodLog10 = math.log10(product)\n\n        if prodLog10 < 10:\n            productString = str(product)\n            return productString + \'e\' + str(zerosCount)\n\n        first = int(pow(10, prodLog10 % 1 + 4))\n        last = product % modulo\n       \n        return str(first) + \'...\' + str(last).zfill(5) + \'e\' + str(zerosCount) \n```
['Number Theory', 'Python3']