<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

339. Segments
Time limit per test: 2.25 second(s)
Memory limit: 65536 kilobytes
input: standard
output: standard



Consider a real axis and segments on it. You are to write a program that processes queries of two kinds.

Query '+ L R' adds a segment from point L to point R. You program should print the number of segments that are (non-strictly) inside the new one.

Query '- L R' removes one segment from point L to point R. If there is no such segment, ignore this query.

You may assume that no more than 1000 segments will present on the axis simultaneously.

Input
Each line of the input file contains one query. Query can be in the form '- L R' or '+ L R', where L and R are integers (-109 ≤ L < R ≤ 109). There will be no more than 250 · 103 queries.

Output
Print to the output one line for each '+ L R' query, containing the number of segments inside the added segment.

Example(s)
sample input
sample output
+ 1 2
+ 1 2
+ 0 3
- 1 2
+ 1 2
0
1
2
1

<|response|>
## 1) Abridged problem statement (concise)

Maintain a multiset of segments \([L,R]\) on the real line under queries until EOF:

- `+ L R`: add segment \([L,R]\), and **print** how many currently active segments \([l,r]\) satisfy \(L \le l\) and \(r \le R\) (i.e., are inside the new segment, endpoints allowed).
- `- L R`: remove **one** occurrence of \([L,R]\) if it exists; otherwise ignore.

Constraints: up to 250,000 queries, coordinates \([-10^9,10^9]\), and **at most 1000 segments are active at any time**.

---

## 2) Key observations

1. **Active set is small (≤ 1000).**  
   Even with 250k queries, the expensive work per query can be linear in the number of active segments and still pass.

2. For a `+ L R` query, a segment \([l,r]\) is inside iff:
   \[
   l \ge L \;\;\text{and}\;\; r \le R
   \]
   So we can just scan all active segments and count.

3. Deletions are “remove one copy”. Duplicates may exist, so we need multiset behavior.

4. Efficient deletion from an array/vector: **swap-with-last + pop**  
   - Find one matching segment index `i`
   - Replace it with the last element
   - `pop_back()`
   This avoids shifting and keeps removal O(1) after the O(A) search.

5. Coordinate compression is optional here (comparisons on original ints work).  
   It can still be used safely because it preserves order, so containment comparisons remain correct.

---

## 3) Full solution approach

### Data structure
Keep currently active segments in two parallel vectors/arrays:
- `Ls[k]` = left endpoint of segment k
- `Rs[k]` = right endpoint of segment k

Active size \(A \le 1000\).

### Processing queries
Read queries until EOF, process sequentially:

- **On `+ L R`:**
  1. Count `cnt = number of k such that Ls[k] >= L and Rs[k] <= R`
  2. Print `cnt`
  3. Insert the new segment by `Ls.push_back(L); Rs.push_back(R)`

- **On `- L R`:**
  1. Find any index `i` with `Ls[i] == L && Rs[i] == R`
  2. If found:
     - `Ls[i] = Ls.back(); Rs[i] = Rs.back();`
     - `pop_back` both
  3. If not found: ignore query

### Complexity
- Each `+`: \(O(A)\) comparisons, \(A \le 1000\)
- Each `-`: \(O(A)\) search, O(1) removal
- Worst-case: \(250000 \times 1000 = 2.5 \times 10^8\) simple checks, acceptable in optimized C++ and typically OK in PyPy/Python with care (because active is small).

---

## 4) C++ implementation (detailed comments)

```cpp
#include <bits/stdc++.h>
using namespace std;

/*
  p339 - Segments

  Key idea: at most 1000 segments are active at any time.
  So for each '+' query we can linearly scan all active segments and count
  those contained in the new one.
  For deletions, we remove one occurrence using swap-with-last + pop.
*/

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Active segments stored in parallel arrays.
    vector<long long> Ls, Rs;
    Ls.reserve(1100);
    Rs.reserve(1100);

    char type;
    long long L, R;

    // Input is a stream of queries until EOF.
    while (cin >> type >> L >> R) {
        if (type == '+') {
            // Count how many existing segments are inside [L, R].
            // Condition: l >= L and r <= R.
            int cnt = 0;
            for (size_t i = 0; i < Ls.size(); ++i) {
                if (Ls[i] >= L && Rs[i] <= R) ++cnt;
            }

            cout << cnt << "\n";

            // Add the new segment to active set.
            Ls.push_back(L);
            Rs.push_back(R);
        } else if (type == '-') {
            // Remove one occurrence of [L, R] if present.
            for (size_t i = 0; i < Ls.size(); ++i) {
                if (Ls[i] == L && Rs[i] == R) {
                    // Swap with last to delete in O(1) time (after search).
                    Ls[i] = Ls.back();
                    Rs[i] = Rs.back();
                    Ls.pop_back();
                    Rs.pop_back();
                    break; // remove only one occurrence
                }
            }
            // If not found, ignore as required.
        }
    }

    return 0;
}
```

Notes:
- This version **does not** do coordinate compression; it’s unnecessary because `long long` safely holds endpoints.
- The editorial’s AVX2 vectorization can speed it up further, but the core solution is exactly the same.

---

## 5) Python implementation (detailed comments)

```python
import sys

def solve() -> None:
    """
    Maintain active segments in two lists (Ls, Rs).
    For '+' queries: linear scan to count segments contained in [L, R], print it, then add.
    For '-' queries: find one matching segment and remove via swap-with-last.
    """

    data = sys.stdin.buffer.read().split()
    # Each query is: type L R => 3 tokens
    # type is b'+' or b'-'
    n = len(data)

    Ls = []
    Rs = []

    out_lines = []
    i = 0
    while i < n:
        t = data[i]      # b'+' or b'-'
        L = int(data[i+1])
        R = int(data[i+2])
        i += 3

        if t == b'+':
            cnt = 0
            # Active size <= 1000 => scan is fine
            for l, r in zip(Ls, Rs):
                if l >= L and r <= R:
                    cnt += 1
            out_lines.append(str(cnt))

            Ls.append(L)
            Rs.append(R)

        else:  # t == b'-'
            # Remove one occurrence if present (ignore if absent)
            for idx in range(len(Ls)):
                if Ls[idx] == L and Rs[idx] == R:
                    # swap with last, then pop
                    Ls[idx] = Ls[-1]
                    Rs[idx] = Rs[-1]
                    Ls.pop()
                    Rs.pop()
                    break

    sys.stdout.write("\n".join(out_lines))

if __name__ == "__main__":
    solve()
```

Notes:
- Uses fast tokenized input (`buffer.read().split()`).
- Works directly with original coordinates; no compression needed.
- Deletion removes only one copy, matching the problem statement.