Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <algorithm>
- #include <cassert>
- #include <ctime>
- using namespace std;
- typedef long long LL;
- const int MAXN = 111111;
- inline LL cross(LL x1, LL y1, LL x2, LL y2) {
- return x1 * y2 - y1 * x2;
- }
- inline LL sqRadius(LL x, LL y) {
- return x * x + y * y;
- }
- inline LL dot(LL x1, LL y1, LL x2, LL y2) {
- return x1 * x2 + y1 * y2;
- }
- struct Point {
- LL x, y;
- Point() {
- x = 0;
- y = 0;
- }
- Point(LL x, LL y) {
- this->x = x;
- this->y = y;
- }
- };
- int n;
- Point points[MAXN];
- int dynMemory[4000000];
- int dynPos = 0;
- int *convexHulls[4 * MAXN + 1];
- int len[4 * MAXN + 1];
- int stack[MAXN];
- int size = 0;
- void build(int v, int l, int r) {
- size = 0;
- for (int i = l; i <= r; i++) {
- if (size > 0 && points[i].x * points[stack[size - 1]].y == points[i].y * points[stack[size - 1]].x) {
- continue;
- }
- stack[size++] = i;
- while (size >= 3) {
- Point &p1 = points[stack[size - 3]], &p2 = points[stack[size - 2]], &p3 = points[stack[size - 1]];
- LL x1 = p2.x - p1.x, y1 = p2.y - p1.y;
- LL x2 = p3.x - p2.x, y2 = p3.y - p2.y;
- LL cr = cross(x1, y1, x2, y2);
- if (cr < 0) {
- break;
- } else {
- stack[size - 2] = stack[size - 1];
- size--;
- }
- }
- }
- convexHulls[v] = &dynMemory[dynPos];
- dynPos += size;
- len[v] = size;
- copy(stack, stack + size, convexHulls[v]);
- if (l < r) {
- int m = (l + r) / 2;
- build(2 * v + 1, l, m);
- build(2 * v + 2, m + 1, r);
- }
- }
- inline LL f(const Point &p, LL nx, LL ny) {
- return dot(nx, ny, p.x, p.y);
- }
- bool get(int v, int tl, int tr, int l, int r, LL x1, LL y1, LL x2, LL y2) {
- if (l > r) {
- return false;
- } else if (tl == l && tr == r) {
- LL vx = x2 - x1, vy = y2 - y1;
- LL nx = vy, ny = -vx;
- int *hull = convexHulls[v];
- if (len[v] == 0) {
- return false;
- }
- int sl = 0, sr = len[v] - 1;
- while (sr - sl >= 3) {
- int m1 = sl + (sr - sl) / 3;
- int m2 = sr - (sr - sl) / 3;
- LL f1 = f(points[hull[m1]], nx, ny);
- LL f2 = f(points[hull[m2]], nx, ny);
- if (f1 >= f2) {
- sl = m1;
- } else {
- sr = m2;
- }
- }
- int best = sl;
- for (int i = sl + 1; i <= sr; i++) {
- if (f(points[hull[i]], nx, ny) < f(points[hull[best]], nx, ny)) {
- best = i;
- }
- }
- if (dot(nx, ny, points[hull[best]].x - x1, points[hull[best]].y - y1) <= 0) {
- return true;
- } else {
- return false;
- }
- } else {
- int tm = (tl + tr) / 2;
- bool result = false;
- result |= get(2 * v + 1, tl, tm, l, min(r, tm), x1, y1, x2, y2);
- result |= get(2 * v + 2, tm + 1, tr, max(tm + 1, l), r, x1, y1, x2, y2);
- return result;
- }
- }
- inline int cmp(const Point &p1, const Point &p2) {
- LL cr = cross(p1.x, p1.y, p2.x, p2.y);
- if (cr < 0) {
- return 1;
- } else if (cr > 0) {
- return -1;
- } else {
- return 0;
- }
- }
- inline bool cmp2(const Point &p1, const Point &p2) {
- LL cr = cross(p1.x, p1.y, p2.x, p2.y);
- if (cr < 0) {
- return false;
- } else if (cr > 0) {
- return true;
- } else {
- LL r1 = sqRadius(p1.x, p1.y);
- LL r2 = sqRadius(p2.x, p2.y);
- if (r1 < r2) {
- return true;
- } else {
- return false;
- }
- }
- }
- inline int lowerBound(const Point &p) {
- int l = -1, r = n;
- while (r - l > 1) {
- int m = (l + r) / 2;
- if (cmp(points[m], p) <= 0) {
- l = m;
- } else {
- r = m;
- }
- }
- return l;
- }
- inline int upperBound(const Point &p) {
- int l = -1, r = n;
- while (r - l > 1) {
- int m = (l + r) / 2;
- if (cmp(points[m], p) >= 0) {
- r = m;
- } else {
- l = m;
- }
- }
- return r;
- }
- int main() {
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- int k, m;
- scanf("%d %d", &k, &m);
- n = k;
- for (int i = 0; i < k; i++) {
- int x, y;
- scanf("%d %d", &x, &y);
- points[i] = Point(x, y);
- }
- sort(points, points + n, cmp2);
- build(0, 0, n - 1);
- for (int i = 0; i < m; i++) {
- int x1, y1, x2, y2;
- scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
- LL cr = cross(x1, y1, x2, y2);
- if (cr < 0) {
- int temp = x1;
- x1 = x2;
- x2 = temp;
- temp = y1;
- y1 = y2;
- y2 = temp;
- }
- int l = upperBound(Point(x1, y1));
- int r = lowerBound(Point(x2, y2));
- puts(get(0, 0, k - 1, l, r, x1, y1, x2, y2) ? "Y" : "N");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment