Mlxa

TEAMBOOK пересечение полуплоскостей

Nov 1st, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.26 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using ld = double;
  3. using ll = long long;
  4. #define double ld
  5. #define long ll
  6. #define all(x) begin(x), end(x)
  7. using namespace std;
  8.  
  9. mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
  10.  
  11. struct Point {
  12.     double x, y;
  13.     Point(double a, double b) : x(a), y(b) {}
  14.     Point() : x(0), y(0) {}
  15. };
  16. istream &operator>>(istream &in, Point &p) {
  17.     int x, y;
  18.     in >> x >> y;
  19.     p.x = x;
  20.     p.y = y;
  21.     return in;
  22. }
  23. ostream &operator<<(ostream &out, Point p) {
  24.     return out << p.x << " " << p.y;
  25. }
  26. double operator%(Point a, Point b) {
  27.     return a.x * b.y - a.y * b.x;
  28. }
  29. double operator*(Point a, Point b) {
  30.     return a.x * b.x + a.y * b.y;
  31. }
  32. Point operator*(Point a, double k) {
  33.     return {a.x * k, a.y * k};
  34. }
  35. Point operator-(Point a, Point b) {
  36.     return {a.x - b.x, a.y - b.y};
  37. }
  38. Point vec(Point a, Point b) {
  39.     return {b.x - a.x, b.y - a.y};
  40. }
  41. Point operator+(Point a, Point b) {
  42.     return {a.x + b.x, a.y + b.y};
  43. }
  44. double turn(Point a, Point b, Point c) {
  45.     return vec(a, b) % vec(a, c);
  46. }
  47. Point inter(Point a, Point b, Point c, Point d) {
  48.     double acd = (vec(a, c) % vec(a, d)) / 2;
  49.     double bdc = (vec(b, d) % vec(b, c)) / 2;
  50.     double s = acd + bdc;
  51.     return a + vec(a, b) * (acd / s);
  52. }
  53. struct Half {
  54.     Point a, b;
  55.     Half(Point x, Point y) : a(x), b(y) {}
  56.     Half() : a(), b() {}
  57. };
  58. istream &operator>>(istream &in, Half &p) {
  59.     return in >> p.a >> p.b;
  60. }
  61. ostream &operator<<(ostream &out, Half p) {
  62.     return out << "HP: " << p.a << " " << p.b;
  63. }
  64. Point inter(Half a, Half b) {
  65.     return inter(a.a, a.b, b.a, b.b);
  66. }
  67. bool inside(Point o, Half a) {
  68.     return turn(a.a, a.b, o) >= 0;
  69. }
  70. bool collinear(Half a, Half b) {
  71.     Point v = vec(a.a, a.b);
  72.     Point u = vec(b.a, b.b);
  73.     return v % u == 0;
  74. }
  75. bool sameDir(Half a, Half b) {
  76.     Point v = vec(a.a, a.b);
  77.     Point u = vec(b.a, b.b);
  78.     return v * u >= 0;
  79. }
  80. int getPlane(double x, double y) {
  81.     if ((x < 0 && y == 0) || y < 0) {
  82.         return -1;
  83.     } else {
  84.         return 1;
  85.     }
  86. }
  87. bool operator<(Half a, Half b) {
  88.     Point v = vec(a.a, a.b);
  89.     Point u = vec(b.a, b.b);
  90.     int vp = getPlane(v.x, v.y), up = getPlane(u.x, u.y);
  91.     if (vp != up) {
  92.         return vp < up;
  93.     } else {
  94.         return v % u > 0;
  95.     }
  96. }
  97. const int N = 1e5;
  98. int hpcnt, sz;
  99. Half h[N];
  100. Half st[N];
  101. Point hpres[N];
  102.  
  103. bool worse(Half a, Half b) {
  104.     return collinear(a, b) && sameDir(a, b) && inside(b.a, a);
  105. }
  106. bool bad(Half a, Half b, Half c) {
  107.     Point p = inter(b, c);
  108.     return !inside(p, a);
  109. }
  110.  
  111. void addHP(Half a) {
  112.     h[hpcnt++] = a;
  113. }
  114.  
  115. void initHP() {
  116.     sz = 0;
  117.     hpcnt = 0;
  118.     const double S = 3e5;
  119.     addHP({{-S, -S}, {+S, -S}});
  120.     addHP({{+S, -S}, {+S, +S}});
  121.     addHP({{+S, +S}, {-S, +S}});
  122.     addHP({{-S, +S}, {-S, -S}});
  123. }
  124.  
  125. void process(int i, bool push) {
  126.     if (sz >= 1 && worse(h[i], st[sz - 1])) {
  127.         return;
  128.     }
  129.     if (sz >= 1 && worse(st[sz - 1], h[i])) {
  130.         --sz;
  131.     }
  132.     while (sz >= 2 && bad(st[sz - 2], st[sz - 1], h[i])) {
  133.         --sz;
  134.     }
  135.     if (push) {
  136.         st[sz++] = h[i];
  137.     }
  138. }
  139.  
  140. void solveHP() {
  141.     stable_sort(h, h + hpcnt);
  142.     sz = 0;
  143.     for (int i = 0; i < hpcnt; ++i) {
  144.         process(i, true);
  145.     }
  146.     for (int i = 0; i < hpcnt; ++i) {
  147.         process(i, true);
  148.     }
  149.     int l = -1, r = -1;
  150.     map<tuple<int, int, int, int>, int> was;
  151.     for (int i = 0; i < sz; ++i) {
  152.         int a = (int)st[i].a.x, b = (int)st[i].a.y, c = (int)st[i].b.x, d = (int)st[i].b.y;
  153.         tuple<int, int, int, int> pp(a, b, c, d);
  154.         if (was.count(pp)) {
  155.             l = was[pp];
  156.             r = i;
  157.             break;
  158.         }
  159.         was[pp] = i;
  160.     }
  161.     sz = r - l;
  162.     for (int i = l; i < r; ++i) {
  163.         hpres[i - l] = inter(st[i], st[i + 1]);
  164.     }
  165. }
  166.  
  167. int n;
  168. Point p[N];
  169.  
  170. double dist(Point a, Point b) {
  171.     return hypot(a.x - b.x, a.y - b.y);
  172. }
  173.  
  174.  
  175. double query(Point q) {
  176.     initHP();
  177.     for (int i = 0, l = i + 1; i < n; ++i) {
  178.         while (turn(p[i], p[l], q) >= 0) {
  179.             ++l;
  180.         }
  181.         --l;
  182.         addHP(Half(p[i], p[l]));
  183.     }
  184.     solveHP();
  185.     double answer = 0;
  186.     for (int i = 0; i < sz; ++i) {
  187.         answer = max(answer, dist(q, hpres[i]));
  188.     }
  189.     return answer;
  190. }  
  191.  
  192. int main() {
  193. #ifdef LC
  194.     assert(freopen("input.txt", "r", stdin));
  195. #endif
  196.     ios::sync_with_stdio(0);
  197.     cin.tie(0);
  198.     cout << fixed << setprecision(10);
  199.     cerr << fixed << setprecision(10);
  200.     cin >> n;
  201.     for (int i = 0; i < n; ++i) {
  202.         cin >> p[i];
  203.         p[i + n] = p[i];
  204.     }
  205.     int m;
  206.     cin >> m;
  207.     while (m--) {
  208.         Point q;
  209.         cin >> q;
  210.         cout << query(q) << "\n";
  211.     }
  212.     return 0;
  213. }
Add Comment
Please, Sign In to add comment