Guest User

Untitled

a guest
Jul 26th, 2013
286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.20 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <algorithm>
  5. #include <cassert>
  6. #include <ctime>
  7. using namespace std;
  8.  
  9. typedef long long LL;
  10.  
  11. const int MAXN = 111111;
  12.  
  13. inline LL cross(LL x1, LL y1, LL x2, LL y2) {
  14.     return x1 * y2 - y1 * x2;
  15. }
  16.    
  17. inline LL sqRadius(LL x, LL y) {
  18.     return x * x + y * y;
  19. }
  20.    
  21. inline LL dot(LL x1, LL y1, LL x2, LL y2) {
  22.     return x1 * x2 + y1 * y2;
  23. }
  24.  
  25. struct Point {
  26.     LL x, y;
  27.  
  28.     Point() {
  29.         x = 0;
  30.         y = 0;
  31.     }
  32.    
  33.     Point(LL x, LL y) {
  34.         this->x = x;
  35.         this->y = y;
  36.     }
  37. };
  38.    
  39. int n;
  40. Point points[MAXN];
  41.  
  42. int dynMemory[4000000];
  43. int dynPos = 0;
  44.  
  45. int *convexHulls[4 * MAXN + 1];
  46. int len[4 * MAXN + 1];
  47.        
  48. int stack[MAXN];
  49. int size = 0;
  50.        
  51. void build(int v, int l, int r) {
  52.     size = 0;
  53.     for (int i = l; i <= r; i++) {
  54.         if (size > 0 && points[i].x * points[stack[size - 1]].y == points[i].y * points[stack[size - 1]].x) {
  55.             continue;
  56.         }
  57.         stack[size++] = i;
  58.         while (size >= 3) {
  59.             Point &p1 = points[stack[size - 3]], &p2 = points[stack[size - 2]], &p3 = points[stack[size - 1]];
  60.             LL x1 = p2.x - p1.x, y1 = p2.y - p1.y;
  61.             LL x2 = p3.x - p2.x, y2 = p3.y - p2.y;
  62.             LL cr = cross(x1, y1, x2, y2);
  63.             if (cr < 0) {
  64.                 break;
  65.             } else {
  66.                 stack[size - 2] = stack[size - 1];
  67.                 size--;
  68.             }
  69.         }
  70.     }
  71.     convexHulls[v] = &dynMemory[dynPos];
  72.     dynPos += size;
  73.     len[v] = size;
  74.     copy(stack, stack + size, convexHulls[v]);
  75.     if (l < r) {
  76.         int m = (l + r) / 2;
  77.         build(2 * v + 1, l, m);
  78.         build(2 * v + 2, m + 1, r);
  79.     }
  80. }
  81.        
  82. inline LL f(const Point &p, LL nx, LL ny) {
  83.     return dot(nx, ny, p.x, p.y);
  84. }
  85.        
  86. bool get(int v, int tl, int tr, int l, int r, LL x1, LL y1, LL x2, LL y2) {
  87.     if (l > r) {
  88.         return false;
  89.     } else if (tl == l && tr == r) {
  90.         LL vx = x2 - x1, vy = y2 - y1;
  91.         LL nx = vy, ny = -vx;
  92.         int *hull = convexHulls[v];
  93.         if (len[v] == 0) {
  94.             return false;
  95.         }
  96.         int sl = 0, sr = len[v] - 1;
  97.         while (sr - sl >= 3) {
  98.             int m1 = sl + (sr - sl) / 3;
  99.             int m2 = sr - (sr - sl) / 3;
  100.             LL f1 = f(points[hull[m1]], nx, ny);
  101.             LL f2 = f(points[hull[m2]], nx, ny);
  102.             if (f1 >= f2) {
  103.                 sl = m1;
  104.             } else {
  105.                 sr = m2;
  106.             }
  107.         }
  108.         int best = sl;
  109.         for (int i = sl + 1; i <= sr; i++) {
  110.             if (f(points[hull[i]], nx, ny) < f(points[hull[best]], nx, ny)) {
  111.                 best = i;
  112.             }
  113.         }
  114.         if (dot(nx, ny, points[hull[best]].x - x1, points[hull[best]].y - y1) <= 0) {
  115.             return true;
  116.         } else {
  117.             return false;
  118.         }
  119.     } else {
  120.         int tm = (tl + tr) / 2;
  121.         bool result = false;
  122.         result |= get(2 * v + 1, tl, tm, l, min(r, tm), x1, y1, x2, y2);
  123.         result |= get(2 * v + 2, tm + 1, tr, max(tm + 1, l), r, x1, y1, x2, y2);
  124.         return result;
  125.     }
  126. }
  127.  
  128. inline int cmp(const Point &p1, const Point &p2) {
  129.     LL cr = cross(p1.x, p1.y, p2.x, p2.y);
  130.     if (cr < 0) {
  131.         return 1;
  132.     } else if (cr > 0) {
  133.         return -1;
  134.     } else {
  135.         return 0;
  136.     }
  137. }
  138.  
  139. inline bool cmp2(const Point &p1, const Point &p2) {
  140.     LL cr = cross(p1.x, p1.y, p2.x, p2.y);
  141.     if (cr < 0) {
  142.         return false;
  143.     } else if (cr > 0) {
  144.         return true;
  145.     } else {
  146.         LL r1 = sqRadius(p1.x, p1.y);
  147.         LL r2 = sqRadius(p2.x, p2.y);
  148.         if (r1 < r2) {
  149.             return true;
  150.         } else {
  151.             return false;
  152.         }
  153.     }
  154. }
  155.    
  156. inline int lowerBound(const Point &p) {
  157.     int l = -1, r = n;
  158.     while (r - l > 1) {
  159.         int m = (l + r) / 2;
  160.         if (cmp(points[m], p) <= 0) {
  161.             l = m;
  162.         } else {
  163.             r = m;
  164.         }
  165.     }
  166.     return l;
  167. }
  168.    
  169. inline int upperBound(const Point &p) {
  170.     int l = -1, r = n;
  171.     while (r - l > 1) {
  172.         int m = (l + r) / 2;
  173.         if (cmp(points[m], p) >= 0) {
  174.             r = m;
  175.         } else {
  176.             l = m;
  177.         }
  178.     }
  179.     return r;
  180. }
  181.    
  182. int main() {
  183.     freopen("input.txt", "r", stdin);
  184.     freopen("output.txt", "w", stdout);
  185.     int k, m;
  186.     scanf("%d %d", &k, &m);
  187.     n = k;
  188.     for (int i = 0; i < k; i++) {
  189.         int x, y;
  190.         scanf("%d %d", &x, &y);
  191.         points[i] = Point(x, y);
  192.     }
  193.     sort(points, points + n, cmp2);
  194.     build(0, 0, n - 1);
  195.     for (int i = 0; i < m; i++) {
  196.         int x1, y1, x2, y2;
  197.         scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
  198.         LL cr = cross(x1, y1, x2, y2);
  199.         if (cr < 0) {
  200.             int temp = x1;
  201.             x1 = x2;
  202.             x2 = temp;
  203.             temp = y1;
  204.             y1 = y2;
  205.             y2 = temp;
  206.         }
  207.         int l = upperBound(Point(x1, y1));
  208.         int r = lowerBound(Point(x2, y2));
  209.         puts(get(0, 0, k - 1, l, r, x1, y1, x2, y2) ? "Y" : "N");
  210.     }
  211. }
Advertisement
Add Comment
Please, Sign In to add comment