Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <chrono>
- #include <random>
- #include <algorithm>
- #include <cassert>
- #include <set>
- std::mt19937 rng((int) std::chrono::steady_clock::now().time_since_epoch().count());
- struct PT {
- typedef long long T;
- T x, y;
- PT(T xx = 0, T yy = 0) : x(xx), y(yy){}
- PT operator +(const PT &p) const { return PT(x+p.x,y+p.y); }
- PT operator -(const PT &p) const { return PT(x-p.x,y-p.y); }
- T operator *(const PT &p) const { return x*p.x+y*p.y; }
- T operator %(const PT &p) const { return x*p.y-y*p.x; }
- bool operator == (const PT &p) const { return x == p.x && y == p.y; }
- bool operator < (const PT &p) const {
- if(*this % p != 0) {
- return *this % p > 0;
- } else {
- return *this * *this < p * p;
- }
- }
- };
- int main() {
- std::ios_base::sync_with_stdio(false); std::cin.tie(NULL);
- int n;
- std::cin >> n;
- std::set<PT> hull;
- for(int i = 0; i < n; i++) {
- PT p;
- std::cin >> p.x >> p.y;
- if(i == 0) {
- hull.insert(p);
- } else {
- // remove from begin
- while(1) {
- auto it = hull.begin();
- if(it == hull.end()) break;
- if(it->x < p.x && it->y < p.y) {
- hull.erase(it);
- } else {
- break;
- }
- }
- while(1) {
- auto it = hull.end();
- if(it == hull.begin()) break;
- it--;
- if(it->x < p.x && it->y < p.y) {
- hull.erase(it);
- } else {
- break;
- }
- }
- // remove from right
- while(1) {
- auto it = hull.lower_bound(p);
- if(it == hull.end()) break;
- if(it->x < p.x && it->y < p.y) {
- hull.erase(it);
- } else {
- break;
- }
- }
- while(1) {
- auto it = hull.lower_bound(p);
- if(it == hull.end()) break;
- auto it2 = it;
- it2++;
- if(it2 == hull.end()) break;
- if((*it-p) % (*it2-p) < 0) {
- hull.erase(it);
- } else {
- break;
- }
- }
- // remove from left
- while(1) {
- auto it = hull.lower_bound(p);
- if(it == hull.begin()) break;
- it--;
- if(it->x < p.x && it->y < p.y) {
- hull.erase(it);
- } else {
- break;
- }
- }
- while(1) {
- auto it = hull.lower_bound(p);
- if(it == hull.begin()) break;
- it--;
- auto it2 = it;
- if(it2 == hull.begin()) break;
- it2--;
- if((*it-p) % (*it2-p) > 0) {
- hull.erase(it);
- } else {
- break;
- }
- }
- // check to insert
- bool valid = true;
- if(hull.size() > 0) {
- auto it = hull.lower_bound(p);
- auto it2 = it;
- if(it == hull.begin()) {
- // check if it is greater than p
- valid = valid && (it->x <= p.x);
- } else if(it == hull.end()) {
- it--;
- valid = valid && (it->y <= p.y);
- } else {
- it2--;
- valid = valid && (p-*it2) % (*it-*it2) >= 0;
- }
- }
- if(valid) {
- hull.insert(p);
- }
- }
- std::cout << i + 1 - (int) hull.size() << '\n';
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement