class Solution:
    def smallestDivisor(self, A: List[int], threshold: int) -> int:
        """ tc O(Nlg(max(A)))
        question sum up : find a smallest divisor to make sum of division at each element in array <= threashold 
                        constrains: (1)each division round up => >= 1 => max divisor is max number in array
                                    (2)divisor is positive  
                                ==> left right ptr found  
       since answer is guaranteed to be found, sum(a/max(A)) <= threshold is ensured   
        """
        l,r = 1, max(A)+1 
        while l < r:
            mid = l + (r-l)//2
            total = 0
            for a in A:
                total += (a+mid-1)//mid 
            if total > threshold: # mid is too small 
                l = mid + 1 
            else:
                r = mid# get smallest mid <= threshold
        return r # or 
############################################### seperate  binary
class Solution:
    def smallestDivisor(self, A: List[int], threshold: int) -> int:
        """tc O(N+NlgM)  N: len(A), M:maxv-minv
        1. set min,max 
        2.compare with threshold
        3. adjust to get smallest divisor 
        """
        minv,maxv = 1,A[0]
        for a in A:
            if a < minv:
                minv = a
            if a > maxv:
                maxv = a
        l,r = minv,maxv
        while l < r:
            mid = l + (r-l)//2
            if self.div_sum(A,threshold,mid):
                r = mid
            else:
                l = mid+1
        return r 
        
    def div_sum(self,A,limit,div):  # return True/ False 
        total = 0
        for a in A:
            total += math.ceil(a/div)
        return total <= limit