cppAcademy
FROM LEARNING TO COMPETING

Proficient.
Put your skills to the test.

Bulgarian Informatics Group B · 2009–2026

217 independently explained problems: 54 Municipal, 54 Regional and 109 National. Start with the easier tasks and work upwards. Difficulty labels are learning estimates, not official ratings; Group B also includes challenging national-level problems. National-round tasks shared by Groups A and B are included. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP B2018 · EasyBinary search

Points in Joined Rectangles

National Olympiad — Municipal round (2018 season)

Submission name: points.cpp

Problem summary

Axis-aligned rectangles stand consecutively from x=0 on the x-axis. Count input points inside their union, including its boundary; repeated input points count separately.

Input

N M; N width-height pairs in left-to-right order; M point coordinates.

Output

The number of included input points.

Constraints

1 ≤ N ≤ 10,000; 1 ≤ M ≤ 100,001; 1 ≤ width,height ≤ 10,000; 0 ≤ x,y ≤ 1,000,000.

Worked example

An independently prepared example for this explanation.

Input

1 4
2 3
1 2
3 7
1 2
0 3

Output

3

Solution analysis

  1. Prefix sums of rectangle widths give their right boundaries. For a point x, lower_bound finds the first right boundary at least x. This rectangle is the only possible containing rectangle, except on a shared vertical boundary.
  2. At a shared boundary, both neighboring rectangles include the point. Compare y with the larger of their heights. At x=0 only the first rectangle applies; at the final right boundary only the last applies.
  3. In official example 2 the union is [0,2]×[0,3]. The point (1,2) is supplied twice and both occurrences count, while (0,3) is on the boundary. Thus the answer is 3.

Why it works

A point strictly between consecutive width-prefix boundaries belongs horizontally to exactly one rectangle, and the height comparison exactly checks vertical membership. At a shared boundary the union contains heights up to the larger adjacent height. The algorithm checks these exhaustive cases and counts each supplied point once.

Complexity: O(N+M log N) time; O(N) space.

Watch out. A shared boundary can belong to the taller rectangle on either side. Keep duplicate points. Do not accept x beyond the total width.

Commented C++17 solution

An independently written complete program with standard headers.

#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m;
    cin>>n>>m;
    vector<int>right(n),height(n);
    int total=0;
    for(int i=0;i<n;i++){
        int width;
        cin>>width>>height[i];
        total+=width;
        right[i]=total;
    }
    int answer=0;
    while(m--){
        int x,y;
        cin>>x>>y;
        auto it=lower_bound(right.begin(),right.end(),x);
        if(it==right.end()){
            continue;
        }
        int index=static_cast<int>(it-right.begin());
        int ceiling=height[index];
        // Both closed rectangles contribute at their shared boundary.
        if(right[index]==x&&index+1<n){
            ceiling=max(ceiling,height[index+1]);
        }
        answer+=y<=ceiling;
    }
    cout<<answer<<'\n';
}

Source: Arena Olimpiici ↗