ConvergingArray
<?xml encoding="utf-8" ?><p>import java.util.*</p><p> </p><p>fun main() {</p><p> val sc = Scanner(System.`in`)</p><p> if (!sc.hasNextInt()) return</p><p> val n = sc.nextInt()</p><p> val c = IntArray(n) { sc.nextInt() }</p><p> val b = IntArray(n - 1) { sc.nextInt() }</p><p> val q = sc.nextInt()</p><p> val x = sc.nextLong()</p><p> </p><p> val MOD = 1_000_000_007</p><p> </p><p> // P_i = \sum_{j=1}^{i-1} (i-j) b_j = P_{i-1} + \sum_{j=1}^{i-2} b_j + (i-(i-1))b_{i-1} ? NO.</p><p> // P_1 = 0</p><p> // P_2 = b_1</p><p> // P_3 = 2*b_1 + b_2</p><p> // P_4 = 3*b_1 + 2*b_2 + b_3</p><p> // P_i = \sum_{j=1}^{i-1} \sum_{k=1}^{j} b_k</p><p> val P = LongArray(n + 1)</p><p> val prefB = LongArray(n)</p><p> for (i in 0 until n - 1) prefB[i + 1] = prefB[i] + b[i]</p><p> P[1] = 0</p><p> for (i in 2..n) {</p><p> P[i] = P[i - 1] + prefB[i - 1]</p><p> }</p><p> </p><p> // max sum is N * max(C) = 100 * 100 = 10000</p><p> val maxSum = n * 100</p><p> var dp = IntArray(maxSum + 1)</p><p> dp[0] = 1</p><p> </p><p> for (i in 1..n) {</p><p> val nextDp = IntArray(maxSum + 1)</p><p> val prefDp = IntArray(maxSum + 2)</p><p> for (s in 0..maxSum) prefDp[s + 1] = (prefDp[s] + dp[s]) % MOD</p><p> </p><p> for (s in 0..maxSum) {</p><p> // Need: i*x - P_i <= current_sum <= s, current_sum = s_prev + a_i</p><p> // a_i in [0, c[i-1]]</p><p> // max a_i is c[i-1]</p><p> // Need to check if s allows the condition \sum_{j=1}^i a_j >= i*x - P_i</p><p> if (s < i * x - P[i]) continue</p><p> </p><p> val minPrevS = Math.max(0, s - c[i - 1])</p><p> val maxPrevS = s</p><p> if (minPrevS <= maxPrevS) {</p><p> var sum = (prefDp[maxPrevS + 1] - prefDp[minPrevS]) % MOD</p><p> if (sum < 0) sum += MOD</p><p> nextDp[s] = sum</p><p> }</p><p> }</p><p> dp = nextDp</p><p> }</p><p> </p><p> var total = 0L</p><p> for (s in dp) {</p><p> total = (total + s) % MOD</p><p> }</p><p> println(total)</p><p>}</p><p> </p><p> </p>