Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- // #define int long long
- #define f first
- #define s second
- using namespace std;
- typedef long long ll;
- const int MOD = 1e9 + 9;
- const int inf = 1e9;
- const double eps = 1e-9;
- const double PI = acos(-1);
- struct point {
- ll x, y;
- point operator - (const point &p) const {
- return point{x - p.x, y - p.y};
- }
- point operator *(ll d) {
- return {x * d, y * d};
- }
- ll operator *(const point &p) {
- return x * p.y - y * p.x;
- }
- bool isRight(point &P) {
- if(P.x > 0) {
- return true;
- }
- return (P.x == 0 && P.y < 0);
- }
- bool operator < (point &p) {
- if(isRight(*this) != isRight(p)) {
- return isRight(*this);
- }
- return *this * p > 0;
- }
- bool operator == (point &p) {
- return (x == p.x && y == p.y);
- }
- void read() {
- double X, Y;
- cin >> X >> Y;
- x = llround(X * 1e6);
- y = llround(Y * 1e6);
- }
- };
- ll orient(point o, point a, point b) {
- return (a - o) * (b - o);
- }
- ostream& operator << (ostream& os, const point &p) {
- return os << "(" << p.x << "," << p.y << ")";
- }
- void insert(vector<point> &hull, point &P) {
- while(hull.size() > 1) {
- int sz = hull.size();
- if(orient(hull[sz - 2], hull[sz - 1], P) >= 0) {
- hull.pop_back();
- }
- else {
- break;
- }
- }
- hull.push_back(P);
- }
- vector<point> compute_hull(vector<point> &red) {
- if(red.size() == 1) {
- return red;
- }
- vector<point> upper;
- int m = red.size();
- for(int i = 0; i < m; ++i) {
- insert(upper, red[i]);
- }
- upper.pop_back();
- vector<point> lower;
- for(int i = m - 1; i >= 0; --i) {
- insert(lower, red[i]);
- }
- lower.pop_back();
- vector<point> ans;
- for(auto it: upper) {
- ans.push_back(it);
- }
- for(auto it: lower) {
- ans.push_back(it);
- }
- return ans;
- }
- bool same_sign(ll a, ll b) {
- return ((a <= 0 && b <= 0) || (a >= 0 && b >= 0));
- }
- bool between(point &angle, point &left_vec, point &right_vec) {
- return (same_sign(left_vec * angle, left_vec * right_vec)
- && same_sign(right_vec * angle, right_vec * left_vec));
- }
- int n, m;
- vector<point> red, blue;
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(0);
- cin >> n >> m;
- blue.resize(n);
- red.resize(m);
- for(int i = 0; i < n; ++i) {
- blue[i].read();
- }
- for(int i = 0; i < m; ++i) {
- red[i].read();
- }
- sort(red.begin(), red.end(), [&](point &a, point &b) {
- if(a.x == b.x) {
- return a.y < b.y;
- }
- return a.x < b.x;
- });
- vector<point> polygon = compute_hull(red);
- int N = polygon.size();
- int ans = 0;
- for(int i = 0; i < N; ++i) {
- point right_vec = polygon[(i + 1) % N] - polygon[i];
- point left_vec = (polygon[(i - 1 + N) % N] - polygon[i]);
- vector<point> angles;
- if(N == 2) {
- left_vec = right_vec * -1;
- }
- for(auto y: blue) {
- point angle = y - polygon[i];
- if(N <= 2) {
- angles.push_back(angle);
- }
- else if(!between(angle, left_vec, right_vec)) {
- // points that are not between vectors
- angles.push_back(angle);
- }
- }
- if(N > 1) {
- angles.push_back(left_vec);
- angles.push_back(right_vec);
- }
- sort(angles.begin(), angles.end());
- int M = angles.size();
- for(int i = 0; i < M; ++i) {
- angles.push_back(angles[i]);
- }
- int R = 0;
- for(int L = 0; L < M; ++L) {
- if(R < L) {
- R = L;
- }
- while(R == L || ((angles[L] * angles[R] > 0))) {
- if(angles[R] == left_vec || angles[R] == right_vec) {
- break;
- }
- R++;
- }
- ans = max(ans, max(0, R - L));
- }
- }
- cout << ans << '\n';
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment