In this post, we will solve Minimum Multiple HackerRank Solution. This problem (Minimum Multiple) is a part of HackerRank Functional Programming series.
Task
Calculi is Lambda’s older brother. Lambda is mischievous and always annoys Calculi by asking silly questions. This time around, Lambda would like to surprise Calculi by asking a challenging and interesting question. To that end, Lambda gives Calculi an array of N integers, A = {a0, a1, . . . , aN-1}, followed by K queries. Each query is of two types:
- Q l r: Find the minimum positive integer, M, such that each element in subarray arr[l . . . r] ({al, al+1, . . . , ar}) divides M.
- U idx val: Multiply the value at idx by val. That is a’idx = aidx x val, where a’idx is the updated value.
Your task is to help Calculi tackle this challenge. For each query of type nQ l rn, find the value of M. As this value can be very large, print the M modulo (109 + 7), i.e., M % (109 + 7). For query of type nU idx valn, update the required element.
Input Format
The first line contains an integer, N, which represents the length of array, A.
In second line, there are N space-separated integers, a0, a1, . . . , aN-1, representing the elements of A.
In third line, there is another integer, K, which is the count of queries to follow.
Then follows K lines, each representing a query of one of the types described above.
Constraints
- 1 <= N <= 5 x 104
- 1 <= ai <= 100, where i ∈[0, N – 1]
- 1 <= K <= 5 x 104
- 0 <= l <= r < N
- 0 <= idx < N
- 1 <= val <= 100
Output Format
For each query of type Q l r
, print the value of M % (109 + 7) on a new line.
Sample Input
5
2 5 6 1 9
7
Q 0 4
U 1 2
Q 0 2
Q 3 4
Q 2 4
U 3 8
Q 2 3
Sample Output
90
30
9
18
24
Explanation
Query 1 (Q 0 4): Calculi has to find M for (sub)array A[0 . . . 4] = {2, 5, 6, 1, 9} which is 90.
Query 2 (U 1 2): a‘1 = a1 x 2 = 10. Now updated array is A = {2, 10, 6, 1, 9}.
Query 3 (Q 0 2): M for subarray A[0 . . . 2] = {2, 10, 6} is 30.
Query 4 (Q 3 4): M for subarray A[3 . . . 4] = {1, 9} is 9.
Query 5 (Q 2 4): M for subarray A[2 . . 4] = {6, 1, 9} is 18.
Query 6 (U 3 8): Updated array is A = {2, 10, 6, 8, 9}.
Query 7 (Q 2 3): M for subarray A[2 . . . 3] = {6, 8} is 24.
Solution – Minimum Multiple – HackerRank Solution
Scala
import java.io.{BufferedReader, IOException, InputStreamReader} import java.util.StringTokenizer import scala.collection.mutable import scala.reflect.ClassTag class FastReader() { val br: BufferedReader = new BufferedReader(new InputStreamReader(System.in)) var st: StringTokenizer = _ def nextInt: Int = next.toInt def nextLong: Long = next.toLong def next: String = { while (st == null || !st.hasMoreElements) try st = new StringTokenizer(br.readLine) catch { case e: IOException => e.printStackTrace() } st.nextToken } def nextDouble: Double = next.toDouble def nextLine: String = { var str = "" try str = br.readLine catch { case e: IOException => e.printStackTrace() } str } } abstract class SegmentTree[Node, Value](seq: IndexedSeq[Value])(implicit tag: ClassTag[Node]) { private val len: Int = seq.length val nodes: Array[Node] = { val defaultNode = emptyNode Array.fill[Node](4 * len)(defaultNode) } def build(v: Int = 1, left: Int = 0, right: Int = len - 1): Unit = { nodes(v) = if (left == right) valueToNode(v, seq(left)) else { val middle = (left + right) >> 1 build(2 * v, left, middle) build(2 * v + 1, middle + 1, right) combine(nodes(2 * v), nodes(2 * v + 1)) } } def valueToNode: (Int, Value) => Node def add(index: Int, value: Value): Unit = traverse(index, i => nodes(i) = valueToNode(i, value)) private def traverse(index: Int, f: Int => Any): Unit = { def inner(v: Int = 1, left: Int = 0, right: Int = len - 1): Unit = if (left == right) f(v) else { val middle = (left + right) >> 1 if (index <= middle) inner(2 * v, left, middle) else inner(2 * v + 1, middle + 1, right) nodes(v) = combine(nodes(2 * v), nodes(2 * v + 1)) } inner() } def remove(index: Int, value: Value): Unit = traverse(index, nodes(_) = emptyNode) def emptyNode: Node def combine(leftNode: Node, rightNode: Node): Node def query[B](leftBound: Int, rightBound: Int, f: (Int, Int, Node) => B, comb: (B, B) => B): B = { def inner(leftBound: Int, rightBound: Int, v: Int = 1, left: Int = 0, right: Int = len - 1): B = if (leftBound == left && rightBound == right) { f(leftBound, rightBound, nodes(v)) } else { val middle = (left + right) >> 1 if (rightBound <= middle) inner(leftBound, rightBound, 2 * v, left, middle) else if (leftBound > middle) inner(leftBound, rightBound, 2 * v + 1, middle + 1, right) else comb( inner(leftBound, middle, 2 * v, left, middle), inner(middle + 1, rightBound, 2 * v + 1, middle + 1, right) ) } inner(leftBound, rightBound) } build() } case class Code(seq: IndexedSeq[Int]) { def toInt: Int = seq.indices.foldLeft(1)((acc, i) => { var n = seq(i) var res: Long = acc val prime = Code.primeNumbers(i) while (n > 0) { res = (res * prime) % Code.modulo n -= 1 } res.toInt }) } object Code { val maxValue = 100 val primeNumbers: IndexedSeq[Int] = (2 to maxValue).filter(v => BigInt(v).isProbablePrime(10)) private val modulo = 1000000007 def apply(value: Int): Code = { @scala.annotation.tailrec def toPrimes(value: Int, index: Int, acc: List[Int]): List[Int] = if (index < primeNumbers.length) { val prime = primeNumbers(index) if (value % prime == 0) toPrimes(value / prime, index, (acc.head + 1) :: acc.tail) else toPrimes(value, index + 1, 0 :: acc) } else acc new Code(toPrimes(value, 0, 0 :: Nil).tail.reverse.toIndexedSeq) } } class MaxTree(seq: IndexedSeq[Int]) extends SegmentTree[Code, Int](seq) { override lazy val emptyNode: Code = Code(1) override def valueToNode: (Int, Int) => Code = (i, v) => { val code = Code(v) val node = nodes(i) Code(code.seq.indices.map(i => code.seq(i) + node.seq(i))) } def query(leftBound: Int, rightBound: Int): Int = super.query(leftBound, rightBound, (_, _, code) => code, combine).toInt override def combine(leftNode: Code, rightNode: Code): Code = Code(leftNode.seq.indices.map(i => math.max(leftNode.seq(i), rightNode.seq(i)))) } object Solution { def main(args: Array[String]): Unit = { val sc = new FastReader val n = sc.nextInt val values = (0 until n).map(_ => sc.nextInt) val tree = new MaxTree(values) val q = sc.nextInt val answer = new mutable.Queue[Int]() (0 until q).foreach(_ => { val tokens = sc.nextLine.split(" ") val op = tokens.head.head val left = tokens(1).toInt val right = tokens(2).toInt op match { case 'Q' => answer.enqueue(tree.query(left, right)) case 'U' => tree.add(left, right) } }) println(answer.mkString("\n")) } }
Note: This problem (Minimum Multiple) is generated by HackerRank but the solution is provided by CodingBroz. This tutorial is only for Educational and Learning purpose.