• + 0 comments

    scala using memo and precomputing:

    import scala.annotation.tailrec
    import scala.collection.mutable
    import scala.io.StdIn
    
    object Solution {
      val memo = mutable.Map.empty[Int, mutable.Map[Int, Int]]
    
      private def precompute(a: Array[Int], dms: Map[Int, Set[Int]]): Unit = {
        val n = a.length
    
        def isValid(i: Int, ad: Int, m: Int): Boolean =
          ad <= a(i) && a(i) <= (ad + m)
    
        @tailrec
        def getLeft(i: Int, ad: Int, m: Int): Int = {
          if (i < 0)
            0
          else if (!isValid(i, ad, m))
            (i + 1)
          else
            getLeft(i - 1, ad, m)
        }
    
        @tailrec
        def getRight(i: Int, ad: Int, m: Int): Int = {
          if (n <= i)
            (n - 1)
          else if (!isValid(i, ad, m))
            (i - 1)
          else
            getRight(i + 1, ad, m)
        }
    
        def getRange(d: Int, ad: Int, m: Int): Int =
          getRight(d + 1, ad, m) - getLeft(d - 1, ad, m) + 1
    
        dms.foreach { case (d, ms) =>
          memo.addOne(d -> mutable.Map.empty)
          ms.foreach(m => memo(d).addOne(m -> getRange(d, a(d), m)))
        }
      }
    
      private def solve(dm: (Int, Int)): Int = {
        val (d, m) = dm
        memo(d)(m)
      }
    
      def main(args: Array[String]): Unit = {
        val in = Iterator
          .continually(StdIn.readLine())
          .takeWhile(null != _)
          .map(_.trim)
        in.next()
        val a = in.next().split(' ').map(_.toInt)
        val q = in.next().toInt
        val queries = (1 to q)
          .map(_ => in.next().split(' ').map(_.toInt))
          .map(dm => dm.head -> dm.last)
        val dms = queries
          .groupBy(_._1)
          .map(g => g._1 -> g._2.map(_._2).toSet)
          .toMap
        precompute(a, dms)
        queries
          .map(solve)
          .foreach(println)
      }
    }