Range and Update Sum Queries with Factorial | Python3 program to calculate sum of factorials in an interval and update with two types of operations ; Modulus ; Maximum size of input array ; Size for factorial array ; structure for queries with members type , leftIndex , rightIndex of the query ; function for updating the value ; function for calculating the required sum between two indexes ; function to return answer to queries ; Precomputing factorials ; Declaring a Set ; inserting indexes of those numbers which are lesser than 40 ; update query of the 1 st type ; find the left index of query in the set using binary search ; if it crosses the right index of query or end of set , then break ; update the value of arr [ i ] to its new value ; if updated value becomes greater than or equal to 40 remove it from the set ; increment the index ; update query of the 2 nd type ; update the value to its new value ; If the value is less than 40 , insert it into set , otherwise remove it ; sum query of the 3 rd type ; Driver Code ; input array using 1 - based indexing ; declaring array of structure of type queries ; answer the Queries
from bisect import bisect_left as lower_bound NEW_LINE MOD = 1e9 NEW_LINE MAX = 100 NEW_LINE SZ = 40 NEW_LINE BIT = [ 0 ] * ( MAX + 1 ) NEW_LINE fact = [ 0 ] * ( SZ + 1 ) NEW_LINE class queries : NEW_LINE INDENT def __init__ ( self , tpe , l , r ) : NEW_LINE INDENT self . type = tpe NEW_LINE self . l = l NEW_LINE self . r = r NEW_LINE DEDENT DEDENT def update ( x , val , n ) : NEW_LINE INDENT global BIT NEW_LINE while x <= n : NEW_LINE INDENT BIT [ x ] += val NEW_LINE x += x & - x NEW_LINE DEDENT DEDENT def summ ( x ) : NEW_LINE INDENT global BIT NEW_LINE s = 0 NEW_LINE while x > 0 : NEW_LINE INDENT s += BIT [ x ] NEW_LINE x -= x & - x NEW_LINE DEDENT return s NEW_LINE DEDENT def answerQueries ( arr : list , que : list , n : int , q : int ) : NEW_LINE INDENT global fact NEW_LINE fact [ 0 ] = 1 NEW_LINE for i in range ( 1 , 41 ) : NEW_LINE INDENT fact [ i ] = int ( ( fact [ i - 1 ] * i ) % MOD ) NEW_LINE DEDENT s = set ( ) NEW_LINE for i in range ( 1 , n ) : NEW_LINE INDENT if arr [ i ] < 40 : NEW_LINE INDENT s . add ( i ) NEW_LINE update ( i , fact [ arr [ i ] ] , n ) NEW_LINE DEDENT else : NEW_LINE INDENT update ( i , 0 , n ) NEW_LINE DEDENT DEDENT for i in range ( q ) : NEW_LINE INDENT if que [ i ] . type == 1 : NEW_LINE INDENT while True : NEW_LINE INDENT s = list ( s ) NEW_LINE s . sort ( ) NEW_LINE it = lower_bound ( s , que [ i ] . l ) NEW_LINE if it == len ( s ) or s [ it ] > que [ i ] . r : NEW_LINE INDENT break NEW_LINE DEDENT que [ i ] . l = s [ it ] NEW_LINE val = arr [ s [ it ] ] + 1 NEW_LINE update ( s [ it ] , fact [ val ] - fact [ arr [ s [ it ] ] ] , n ) NEW_LINE arr [ s [ it ] ] += 1 NEW_LINE if arr [ s [ it ] ] >= 40 : NEW_LINE INDENT s . remove ( it ) NEW_LINE DEDENT que [ i ] . l += 1 NEW_LINE DEDENT DEDENT elif que [ i ] . type == 2 : NEW_LINE INDENT s = set ( s ) NEW_LINE idx = que [ i ] . l NEW_LINE val = que [ i ] . r NEW_LINE update ( idx , fact [ val ] - fact [ arr [ idx ] ] , n ) NEW_LINE arr [ idx ] = val NEW_LINE if val < 40 : NEW_LINE INDENT s . add ( idx ) NEW_LINE DEDENT else : NEW_LINE INDENT s . remove ( idx ) NEW_LINE DEDENT DEDENT else : NEW_LINE INDENT print ( ( summ ( que [ i ] . r ) - summ ( que [ i ] . l - 1 ) ) ) NEW_LINE DEDENT DEDENT DEDENT if __name__ == " _ _ main _ _ " : NEW_LINE INDENT q = 6 NEW_LINE arr = [ 0 , 1 , 2 , 1 , 4 , 5 ] NEW_LINE n = len ( arr ) NEW_LINE que = [ queries ( 3 , 1 , 5 ) , queries ( 1 , 1 , 3 ) , queries ( 2 , 2 , 4 ) , queries ( 3 , 2 , 4 ) , queries ( 1 , 2 , 5 ) , queries ( 3 , 1 , 5 ) ] NEW_LINE answerQueries ( arr , que , n , q ) NEW_LINE DEDENT