• + 0 comments

    I am not able to pass many testcases. in python3 it is giving 9 marks in pypy3 it is giving 53 marks. I don't know if there could be better solutions than the editorial solution.

    from math import ceil, log2
    
    base = 1 << 17
    sum_ = []
    min_ = []
    max_ = []
    lazy = []
    
    Inf = 1 << 18
    
    
    def fun(p, q):
        if p >= 0:
            return p // q
        return -((-p + q - 1) // q)
    
    
    def initialize(arr):
        global base, sum_, min_, max_, lazy
        base = (1 << ceil(log2(len(arr))))
        sum_ = [0] * (base * 2)
        min_ = [Inf] * (base * 2)
        max_ = [-Inf] * (base * 2)
        lazy = [0] * (base * 2)
        for i in range(len(arr)):
            sum_[base + i] = min_[base + i] = max_[base + i] = arr[i]
        for i in range(base - 1, -1, -1):
            update(i)
    
    
    def update(i):
        min_[i] = min(min_[2 * i], min_[2 * i + 1])
        max_[i] = max(max_[2 * i], max_[2 * i + 1])
        sum_[i] = sum_[2 * i] + sum_[2 * i + 1]
    
    
    def _put(i, val, length):
        lazy[i] += val
        min_[i] += val
        max_[i] += val
        sum_[i] += (val * length)
    
    
    def put(l, r, delta):
        def util1(l, r, si, ss, se):
            if l <= ss and se <= r:
                _put(si, delta, se - ss)
                return
            if r <= ss or se <= l:
                return
            mid = (ss + se) // 2
            push(si, ss, se)
            util1(l, r, 2 * si, ss, mid)
            util1(l, r, 2 * si + 1, mid, se)
            update(si)
    
        util1(l, r, 1, 0, base)
    
    
    def push(i, ss, se):
        if lazy[i]:
            length = (se - ss) // 2
            _put(2 * i, lazy[i], length)
            _put(2 * i + 1, lazy[i], length)
            lazy[i] = 0
    
    
    def getSum(l, r):
        def util(ss, se, si=1):
            if l <= ss and se <= r:
                return sum_[si]
            if r <= ss or se <= l:
                return 0
            mid = (ss + se) // 2
            push(si, ss, se)
            return util(ss, mid, 2 * si) + util(mid, se, 2 * si + 1)
    
        return util(0, base, 1)
    
    
    def getMax(l, r):
        def util(ss, se, si):
            if l <= ss and se <= r:
                return max_[si]
            if r <= ss or se <= l:
                return -Inf
            mid = (ss + se) // 2
            push(si, ss, se)
            return max(util(ss, mid, 2 * si), util(mid, se, 2 * si + 1))
    
        return util(0, base, 1)
    
    
    def getMin(l, r):
        def util(ss, se, si):
            if l <= ss and se <= r:
                return min_[si]
            if r <= ss or se <= l:
                return Inf
            mid = (ss + se) // 2
            push(si, ss, se)
            return min(util(ss, mid, 2 * si), util(mid, se, 2 * si + 1))
    
        return util(0, base, 1)
    
    
    def divide(l, r, x):
        def util(x, si, ss, se):
            if x == 1:
                return
            if l <= ss and se <= r:
                d1 = fun(min_[si], x) - min_[si]
                d2 = fun(max_[si], x) - max_[si]
                if d1 == d2:
                    _put(si, d1, se - ss)
                    return
            if r <= ss or se <= l:
                return
            mid = (ss + se) // 2
            push(si, ss, se)
            util(x, si * 2, ss, mid)
            util(x, si * 2 + 1, mid, se)
            update(si)
    
        util(x, 1, 0, base)
    
    
    if __name__ == '__main__':
        s = ''
        nq = input().split()
    
        n = int(nq[0])
    
        q = int(nq[1])
    
        box = list(map(int, input().rstrip().split()))
        # print(box)
    
        initialize(box)
        for _ in range(q):
            query = list(map(int, input().split()))
            if query[0] == 1:
                l, r, c = query[1:]
                put(l, r + 1, c)
            elif query[0] == 2:
                l, r, d = query[1:]
                divide(l, r + 1, d)
            elif query[0] == 3:
                l, r = query[1:]
                s += str(getMin(l, r + 1)) + '\n'
            else:
                l, r = query[1:]
                s += str(getSum(l, r + 1)) + '\n'
    
        print(s)