Mlxa

TEAMBOOK Платные дороги

Nov 1st, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.34 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using ld = long 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. int cmp(double a, double b) {
  12.     const double EPS = 1e-9;
  13.     if (abs(a - b) <= EPS) {
  14.         return 0;
  15.     } else if (a < b) {
  16.         return -1;
  17.     } else {
  18.         return +1;
  19.     }
  20. }
  21.  
  22. struct Point {
  23.     double x, y;
  24.     Point(double a, double b) : x(a), y(b) {}
  25.     Point() : Point(0, 0) {}
  26. };
  27. istream &operator>>(istream &in, Point &p) {
  28.     int x, y;
  29.     in >> x >> y;
  30.     p.x = x;
  31.     p.y = y;
  32.     return in;
  33. }
  34. ostream &operator<<(ostream &out, Point p) {
  35.     return out << p.x << " " << p.y;
  36. }
  37. ld operator%(Point a, Point b) {
  38.     return a.x * b.y - a.y * b.x;
  39. }
  40. Point operator-(Point a, Point b) {
  41.     return {a.x - b.x, a.y - b.y};
  42. }
  43. Point operator+(Point a, Point b) {
  44.     return {a.x + b.x, a.y + b.y};
  45. }
  46. bool operator<(Point a, Point b) {
  47.     if (cmp(a.x, b.x)) {
  48.         return a.x < b.x;
  49.     }
  50.     return a.y < b.y;
  51. }
  52.  
  53. int turn(Point a, Point b, Point c) {
  54.     return cmp((b - a) % (c - a), 0);
  55. }
  56.  
  57. const int N = 2e5;
  58. int n, m, us = 0, ds = 0;
  59. double lA[N], lB[N], lC[N];
  60. Point p[N], u[N], d[N];
  61. pair<double, Point> sorted[N];
  62.  
  63. Point findBorder(double x, double y) {
  64.     double ang = atan2(-x, y);
  65.     int i = (lower_bound(sorted, sorted + n, make_pair(ang, Point(0, 0))) - sorted) % n;
  66.     return sorted[i].second;
  67. }
  68.  
  69. bool fastQuery(double A, double B, double C) {
  70.     Point a = findBorder(A, B);
  71.     Point b = findBorder(-A, -B);
  72.     int x = cmp(a.x * A + a.y * B + C, 0);
  73.     int y = cmp(b.x * A + b.y * B + C, 0);
  74.     return x * y <= 0;
  75. }
  76.  
  77. bool slowQuery(double A, double B, double C) {
  78.     bool le = false, gr = false;
  79.     for (int i = 0; i < n; ++i) {
  80.         int c = cmp(A * p[i].x + B * p[i].y + C, 0);
  81.         if (c == 0) {
  82.             return true;
  83.         }
  84.         if (c < 0) {
  85.             le = true;
  86.         } else {
  87.             gr = true;
  88.         }
  89.     }
  90.     return le && gr;
  91. }
  92.  
  93. int main() {
  94. #ifdef LC
  95.     assert(freopen("input.txt", "r", stdin));
  96. #else
  97.     assert(freopen("highways.in", "r", stdin));
  98.     assert(freopen("highways.out", "w", stdout));
  99. #endif
  100.     ios::sync_with_stdio(0);
  101.     cin.tie(0);
  102.     cout << fixed << setprecision(10);
  103.     cerr << fixed << setprecision(10);
  104.    
  105.     cin >> m >> n;
  106.     for (int i = 0; i < m; ++i) {
  107.         cin >> lA[i] >> lB[i] >> lC[i];
  108.     }
  109.     for (int i = 0; i < n; ++i) {
  110.         cin >> p[i];
  111.     }
  112.    
  113.     sort(p, p + n, [&](Point a, Point b) {
  114.         int x = cmp(a.x, b.x);
  115.         if (x) {
  116.             return x < 0;
  117.         }
  118.         return cmp(a.y, b.y) < 0;
  119.     });
  120.    
  121.     u[us++] = p[0];
  122.     d[ds++] = p[0];
  123.     for (int i = 1; i < n; ++i) {
  124.         if (i == n - 1 || turn(p[0], p[i], p[n - 1]) < 0) {
  125.             while (us >= 2 && turn(u[us - 2], u[us - 1], p[i]) >= 0) {
  126.                 --us;
  127.             }
  128.             u[us++] = p[i];
  129.         }
  130.         if (i == n - 1 || turn(p[0], p[i], p[n - 1]) > 0) {
  131.             while (ds >= 2 && turn(d[ds - 2], d[ds - 1], p[i]) <= 0) {
  132.                 --ds;
  133.             }
  134.             d[ds++] = p[i];
  135.         }
  136.     }
  137.     n = ds;
  138.     copy(d, d + n, p);
  139.     for (--us; us > 1; ) {
  140.         p[n++] = u[--us];
  141.     }
  142.     p[n] = p[0];
  143.    
  144.     for (int i = 0; i < n; ++i) {
  145.         Point v = p[i + 1] - p[i];
  146.         sorted[i] = {atan2(v.y, v.x), p[i]};
  147.     }
  148.     sort(sorted, sorted + n);
  149.     vector<int> answer;
  150.     for (int qr = 0; qr < m; ++qr) {
  151.         bool f = fastQuery(lA[qr], lB[qr], lC[qr]);
  152.         if (f) {
  153.             answer.push_back(qr + 1);
  154.         }
  155.     }
  156.     cout << answer.size() << "\n";
  157.     for (int e : answer) {
  158.         cout << e << " ";
  159.     }
  160.     cout << "\n";
  161.    
  162.     return 0;
  163. }
Add Comment
Please, Sign In to add comment