Bear and Rectangle Strips
Contest: VK Cup 2017 - Round 1
Difficulty rating: 3000
Tags: dp, greedy

Limak has a grid that consists of 2 rows and n columns. The j-th cell in the i-th row contains an integer ti, j which can be positive, negative or zero.

A non-empty rectangle of cells is called nice if and only if the sum of numbers in its cells is equal to 0.

Limak wants to choose some nice rectangles and give them to his friends, as gifts. No two chosen rectangles should share a cell. What is the maximum possible number of nice rectangles Limak can choose?

Input format:
The first line of the input contains an integer n (1 ≤ n ≤ 300 000) — the number of columns in the grid.

The next two lines contain numbers in the grid. The i-th of those two lines contains n integers ti, 1, ti, 2, ..., ti, n ( - 109 ≤ ti, j ≤ 109).

Output format:
Print one integer, denoting the maximum possible number of cell-disjoint nice rectangles.

Constraints:
Time limit: 3.0 s
Memory limit: 256.0 MB

Note:
In the first sample, there are four nice rectangles:

Limak can't choose all of them because they are not disjoint. He should take three nice rectangles: those denoted as blue frames on the drawings.

In the second sample, it's optimal to choose six nice rectangles, each consisting of one cell with a number 0.

In the third sample, the only nice rectangle is the whole grid — the sum of all numbers is 0. Clearly, Limak can choose at most one nice rectangle, so the answer is 1.

Example input:
6
70 70 70 70 70 -15
90 -60 -30 30 -30 15

Example output:
3

Example input:
4
0 -1 0 0
0 0 1 0

Example output:
6

Editorial:
There are three types of rectangles: in the top row, in the bottom row, and in both rows (with height 2). For each type, and for each starting index i we can quite easily find the first possible ending index - it's the first index on the right with the same prefix sum of numbers (it means that the difference of prefix sums is 0). We can iterate from right to left for each of three types, use store prefix sums in the set and for each type and each starting index we can remember the first possible ending index (or we will know that there is no such index). The complexity of this part is $${ \mathcal { O } } ( n \cdot \log n )$$.
Now, the naive square solution would be to create an array dp[n][n] and compute dp[i][j] as the maximum possible score, if we are allowed to use only first i cells in the first row and first j cells in the second row. Thanks to the precomputing above, we can move from a state in O(1), considering the following options:
• increase i by 1 (without taking any rectangle)
• increase j by 1
• take the first possible rectangle in the first row (check what is the first possible ending index of a rectangle in the first row, starting at index i + 1)
• take the first possible rectangle in the second row
• if i = j, also consider taking first possible rectangle of height 2 (in both rows)
Now let's improve this part to O(n). Let Ci denote the best score if we were allowed to use only first i cells in each row (Ci = dp[i][i]). It turns out that the following values for each i are enough to solve the problem:
• Ci
• If we were allowed to use only first i cells in the first row, how far we must go in the second row, in order to get the score Ci + 1. In other words, what is the smallest j such that dp[i][j] = Ci + 1
• Similarly, the smallest j such that dp[j][i] = Ci + 1
Take a look at the drawings below. The value Ci is the maximum possible score for light-blue cells on the left drawing. The right drawing shows the third of situation listed above - we want to know what prefix of cells in the first row is needed, if we want to get the score Ci + 1.
To see that it works, we must prove that we don't have to care how far we must go in one row to get the score Ci + 2 or higher. The crucial observation that getting score at least Ci + 2 means that we took at least two rectangles that are at least partially on the right from index i (i.e. each of them contains at least one cell with index greater than i) - see the drawing below. So, instead of considering this situation now, we can first take some rectangle in the second row (or skip a few cells) because we can take that last rectangle in the first row later. In other words, when we are in the state dp[i][j] where i < j, it's enough to consider taking a rectangle in the first row or just increasing i without taking anything.