Official Analysis (C++, Java)

Explanation

Let's start with the brute force solution.

We can iterate over all kk from 02M0…2M along with all pairs of intervals (ai,bi)(a_i, b_i) and (aj,bj)(a_j, b_j). For each combination, we increment our answer if ai+ajkbi+bja_i + a_j \le k \le b_i + b_j. This runs in O(MN2)\mathcal{O}(MN^{2}), which is extremely slow.

Consider the two following optimizations:

Optimization 1

Instead of considering each individual kk, we can think of it as a pair of intervals contributing to all kk from ai+aja_i + a_j to bi+bjb_i + b_j. To count this efficiently, we can use difference arrays, where we do range updates by incrementing position ai+aja_i + a_j by one and decrementing position bi+bj+1b_i + b_j + 1 by one. This improves the time complexity to O(N2+M)\mathcal{O}(N^{2}+M).

Optimization 2

We should probably take advantage of the fact that MM is relatively small. Instead of looping through all pairs of left endpoints (ai,aj)(a_i, a_j) and right endpoints (bi,bj)(b_i, b_j) in O(N2)\mathcal{O}(N^2) time, we can iterate over all distinct left endpoint and right endpoint pairs to process multiple at once in O(M2)\mathcal{O}(M^2). We can then multiply the frequencies of each pair of aia_i values and each pair of bib_i values to count how many times ai+aja_i + a_j and bi+bj+1b_i + b_j + 1 occur among all interval pairs.

Implementation

Time Complexity: O(N+M2)\mathcal{O}\left(N+M^2\right)

C++

#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<pair<int, int>> intervals(n);
for (auto &interval : intervals) { cin >> interval.first >> interval.second; }

Java

import java.io.*;
import java.util.StringTokenizer;
public class ConvolutedIntervals {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer tokenizer = new StringTokenizer(in.readLine());
int n = Integer.parseInt(tokenizer.nextToken());
int m = Integer.parseInt(tokenizer.nextToken());

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!