summaryrefslogtreecommitdiff
path: root/PlaygroundCpp/Sources/Playground.cpp
blob: dbb916c4ffdb4ebe4c0dae64a309179135814c41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <algorithm>
#include <iostream>
#include <climits>
#include <vector>
//#include <gtest/gtest.h>

using std::vector;

struct Segment {
	int start, end;
	bool operator==(const Segment &s1) {
		return (start == s1.start && end == s1.end);
	}
};

bool sortSeg(Segment i, Segment j) {
	if (i.start == j.start) {
		return i.end < j.end;
	}
	return i.start < j.start;
}
vector<int> fast_count_segments(vector<int> starts, vector<int> ends,
		vector<int> points) {
	// Implement algo described here, really clever:
	// https://www.coursera.org/learn/algorithmic-toolbox/discussions/all/threads/QJ1jK9wNEeWdPBL2iFTrAw/replies/Ihiw4txhEeWK5g7mfcS2Xw/comments/oyAMaeIiEeWyqwpvChh66Q
	// l->1, p->2, r->3 for Segment.end property
	vector<Segment> s(starts.size() + ends.size() + points.size());
	vector<Segment> p(points.size());
	Segment tempSeg;
	for (int i = 0; i < p.size(); i++) {
		tempSeg = {points[i], i};
		p[i] = tempSeg;
		tempSeg = {points[i], 2};
		s[2 * starts.size() + i] = tempSeg;
	}
	for (int i = 0; i < starts.size(); i++) {
		tempSeg = {starts[i], 1};
		s[i] = tempSeg;
		tempSeg = {ends[i], 3};
		s[i + starts.size()] = tempSeg;
	}
	std::sort(s.begin(), s.end(), sortSeg);
	std::sort(p.begin(), p.end(), sortSeg);
	vector<int> results(points.size());
	int count = 0;
	int j = 0;
	for (int i = 0; i < s.size(); i++) {
		if (s[i].end == 1) {
			count = count + 1;
		}
		if (s[i].end == 2) {
			results[j] = count;
			j = j + 1;
		}
		if (s[i].end == 3) {
			count = count - 1;
		}
	}
	vector<int> finalResults(points.size());
	for (int i = 0; i < finalResults.size(); i++) {
		finalResults[p[i].end] = results[i];
	}
	return finalResults;
}

//TEST(SortSegment, Sort1) {
//	vector<int> starts = { 0, 7 };
//	vector<int> ends = { 5, 10 };
//	vector<int> points = { 1, 6, 11 };
//	vector<int> results = { 1, 0, 0 };
//
//	vector<int> cnt = fast_count_segments(starts, ends, points);
//
//	ASSERT_EQ(cnt[0], 1);
//	ASSERT_EQ(cnt[1], 0);
//	ASSERT_EQ(cnt[2], 0);
//	ASSERT_EQ(cnt.size(), 3);
//}

int main() {
  int n, m;
  std::cin >> n >> m;
  vector<int> starts(n), ends(n);
  for (size_t i = 0; i < starts.size(); i++) {
    std::cin >> starts[i] >> ends[i];
  }
  vector<int> points(m);
  for (size_t i = 0; i < points.size(); i++) {
    std::cin >> points[i];
  }
  //use fast_count_segments
  vector<int> cnt = fast_count_segments(starts, ends, points);
  for (size_t i = 0; i < cnt.size(); i++) {
    std::cout << cnt[i] << ' ';
  }
}