---
id: springboards
title: "Max Suffix Query with Insertions Only"
author: Benjamin Qi
prerequisites: 
 - harder-ordered
description: "A solution to USACO Gold - Springboards."
frequency: 1
---

import { Problem } from "../models";

export const problems = {
    sample: [
      new Problem("Gold", "Springboards", "995", "Hard", false, [], ""),
    ],
    problems: [
      new Problem("Plat", "Nocross", "721", "Hard", false, [], ""),
      new Problem("CF", "Karen & Cards", "contest/815/problem/D", "Very Hard", false, [], "For each a from p to 1, calculate the number of possible cards with that value of a."),
      new Problem("CF", "GP of Korea 19 - Interesting Drug", "gym/102059/problem/K", "Very Hard", false, [], "Genfuncs not required but possibly helpful"),
    ]
};

<Problems problems={problems.sample} />

<br/>

To solve this problem, we need a data structure that supports operations similar to the following:

  1. Add a pair $(a,b)$.
  2. For any $x$, query the maximum value of $b$ over all pairs satisfying $a\ge x$.

This can be solved with a **segment tree** (see "Point Update Range Sum"), but a simpler option is to use a map. We rely on the fact
that if there exist pairs $(a,b)$ and $(c,d)$ in the map such that $a\le c$ and $b\le d$, we can simply ignore $(a,b)$ (and the answers to future queries will not be affected). So at every point in time, the pairs $(a_1,b_1),(a_2,b_2),\ldots,(a_k,b_k)$ that we store in the map will satisfy $a_1 < a_2 < \cdots < a_k$ and $b_1 > b_2 > \cdots > b_k$. 

  - Querying for a certain $x$ can be done with a single `lower_bound` operation, as we just want the minimum $i$ such that $a_i\ge x$.
  - When adding a pair $(a',b')$, first check if there exists $(a,b)$ already in the map such that $a\ge a', b\ge b'$. 
    - If so, then do nothing.
    - Otherwise, insert $(a',b')$ into the map and repeatedly delete pairs $(a,b)$ such that $a\le a', b\le b'$ from the map until none remain.

If there are $N$ insertions, then each query takes $O(\log N)$ time and adding a pair takes $O(\log N)$ time amortized.

<LanguageSection>

<CPPSection>

```cpp
#define f first
#define s second
#define lb lower_bound

map<int,ll> m;
void ins(int a, ll b) {
  auto it = m.lb(a); if (it != end(m) && it->s >= b) return;
  it = m.insert(it,{a,b}); it->s = b;
  while (it != begin(m) && prev(it)->s <= b) m.erase(prev(it));
}
ll query(int x) { auto it = m.lb(x); 
  return it == end(m) ? 0 : it->s; } 
// it = end(m) means that no pair satisfies a >= x
```

</CPPSection>

<JavaSection>



</JavaSection>

</LanguageSection>

## Problems

(easier examples?)

<IncompleteSection />

<Problems problems={problems.problems} />
