Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem H: Sequence

Problem

項数$L$の等差数列が$N$個ある。$i$番目の等差数列の初項は$a_i$で公差は$d_i$である。1番目の数列から順番に1番目の数列, 2番目の数列, ..., $N$番目の数列と並べ、そうしてできた数列を$A$とする。その後、$A$から長さ$K$の任意の区間を選んで、新たに数列$B$を作るとき、数列$B$の和を最大化せよ。

Input

入力は以下の形式で与えられる。

$N$ $L$ $K$

$a_1$ $d_1$

$a_2$ $d_2$

...

$a_N$ $d_N$

1行目に3つの整数$N$, $L$, $K$が空白区切りで与えられる。

続く$N$行に、$i$個目の等差数列の情報$a_i$, $d_i$が空白区切りで与えられる。

Constraints

入力は以下の条件を満たす。

$1 \leq N \leq 10^5$

$1 \leq L \leq 10^5$

$1 \leq K \leq N\times L$

$0 \leq a_i \leq 10^5$

$1 \leq d_i \leq 10^3$

入力はすべて整数

Output

数列$B$の和の最大値を1行に出力する。

Sample Input 1

3 3 5
0 3
2 2
4 1

Sample Output 1

25

数列$A$は$0,3,6,2,4,6,4,5,6$となる。この数列の第5項から第9項までを数列$B$とすれば、数列$B$の和は25となり、これが最大である。

Sample Input 2

3 3 5
0 10
8 1
11 1

Sample Output 2

58

Solution in Scala (judge verdict: Runtime Error)

import java.util.Scanner

object Main extends App {
  val in = new Scanner(System.in)
  val N = in.nextInt()
  val L = in.nextInt()
  val K = in.nextLong()
  val ad: Array[(Long, Long)] = (for (_ <- 0 until N) yield {
    val a: Long = in.nextInt()
    val d: Long = in.nextInt()
    (a, d)
  }).toArray

  val sum = ad.map {
    case (a, d) => (a + (a + (L - 1) * d)) * L / 2
  }

  // imos[i+1] = sum(0...i)
  val imos = new Array[Long](N + 1)
  for (i <- 0 until N) {
    imos(i + 1) = imos(i) + sum(i)
  }


  def calc(a0: Long, da: Long, b0: Long, db: Long, p: Int): Long = {
    def value(x: Int): Long = (b0 - a0) * x + x * (x - 1) * (db - da) / 2

    val left = 0
    val right = value(p)
    if (db - da > 0) {
      math.max(left, right)
    } else {
      var l = 0
      var r = p
      for (_ <- 0 until 100) {
        val w = (r - l) / 3
        if (value(l) < value(r)) {
          l += w
        } else {
          r += w
        }
      }

      (for {
        x <- (l - 5) to (r + 5)
        if x >= 0 && x <= p
      } yield value(x)).max
    }
  }


  if (K == N * L) {
    println(imos(N))
  } else {
    val ans = (for {
      head <- 0 until N
      if head + K / L < N
    } yield {
      val a0 = ad(head)._1
      val da = ad(head)._2

      val idx = (head + K / L).toInt
      val rest = (K % L).toInt
      val p = L - rest

      val b0 = ad(idx)._1 + rest * ad(idx)._2
      val db = ad(idx)._2

      val sum1 = imos(idx) - imos(head) + (ad(idx)._1 + ad(idx)._1 + (rest - 1) * db) * rest / 2
      val sum2 = calc(a0, da, b0, db, p) + sum1

      if (idx + 1 < N && rest >= 2) {
        val sum3 = sum1 + (b0 + b0 + (p - 1) * db) * p / 2 - (a0 + a0 + (p - 1) * da) * p / 2

        val c0 = ad(idx + 1)._1
        val dc = ad(idx + 1)._2

        val ax = a0 + p * da

        val sum4 = calc(ax, da, c0, dc, rest) + sum3

        math.max(sum2, sum4)
      } else {
        sum2
      }
    }).max
    println(ans)
  }
}