my friends kept on asking me for help on this one silver problem, and to be fair, it is pretty hard the fact that benq's editorial reads like some post-college math paper doesn't help either

(my solution requires knowledge of prefix sums tho)

but without further ado, here's my solution

we have a crap ton of intervals (between 0 and 5000, this will come in use later)

and for...each number in the range...0 to 10k, we want...the number of pairs of intervals whose
start values sum to at most that number and ends sum to at least that number? wth, benq?

now the pleb's method would be a standard brute force to iterate through each number and then legit
go through all pairs of intervals to see what the answer is- that's \(O(M \cdot N^2)\), which is def too slow
**ahahahah**

tbh the main reason this problem's so hard is bc it just... seems too abstract, yknow?

so let's try and make it, well, not so abstract.

let's first think about it from the interval pair's perspective

we'll use the sample input's `[1, 3]` and `[2, 5]` as our example

they sum to the interval `[3, 8]`

notice! that this pair contributes exactly 1 to every answer within `[3, 8]`

what this means is that *because this interval exists*,
every \(k\) value in `[3, 8]` is now 1 greater

and this is exactly the case for all the other interval pairs

try it yourself, i swear it works

now we can just iterate through all interval pairs and do a prefix sum thing at the end to
get all the numbers we need in one fell swoop in ...\(O(M + N^2)\)? that's kinda better? i guess?

look i swear this works, we just need to iterate through all pairs w/o iterating through all the pairs

i know it's hard, but there is a method to do it

this is where the intervals being less than 5000 comes into play

ok so first of all, we just need to increment the start & end (because it's prefix sums)

because of this, let's try processing multiple start-pairs and multiple end-pairs at the same time!

this code below has `startNum` and `endNum`- the first keeps track of the number
of intervals that start at a given location while the second does the same for the endings

now we can just iterate through all pairs of starting locations and all pairs of
ending locations and increment our prefix sums array accordingly

note that this does treat the start and end of each interval almost like completely separately,
but it still works

and now we have our final complexity of O(N + M^2)!

implementation here:

```java import java.io.*; import java.util.*; /** * 2021 dec silver * 2 5 * 1 3 * 2 5 * should output these numbers, each on a new line: * [0, 0, 1, 3, 4, 4, 4, 3, 3, 1, 1] */ public class ConvIntervals { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); BufferedReader read = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer initial = new StringTokenizer(read.readLine()); int intervalNum = Integer.parseInt(initial.nextToken()); int maxMag = Integer.parseInt(initial.nextToken()); int[] startNum = new int[maxMag + 1]; int[] endNum = new int[maxMag + 1]; for (int i = 0; i < intervalNum; i++) { int[] interval = Arrays.stream(read.readLine().split(" ")).mapToInt(Integer::parseInt).toArray(); if (interval[0] > interval[1]) { throw new IllegalArgumentException("invalid interval i hate you"); } startNum[interval[0]]++; endNum[interval[1]]++; } long[] coveredNum = new long[2 * maxMag + 2]; for (int i = 0; i <= maxMag; i++) { for (int j = 0; j <= maxMag; j++) { coveredNum[i + j] += (long) startNum[i] * startNum[j]; coveredNum[i + j + 1] -= (long) endNum[i] * endNum[j]; } } // get the actual array from the initial stuff we constructed long currAmt = 0; for (int i = 0; i <= 2 * maxMag; i++) { currAmt += coveredNum[i]; coveredNum[i] = currAmt; } StringBuilder ans = new StringBuilder(); for (int i = 0; i <= 2 * maxMag; i++) { ans.append(coveredNum[i]).append('\n'); } System.out.print(ans); System.err.printf("it took %d ms, i hope you're happy", System.currentTimeMillis() - start); } } ```