Advertisement
Guest User

Inside/Outside Point

a guest
Nov 13th, 2019
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.36 KB | None | 0 0
  1. #include <limits.h>
  2. #include <vector>
  3. #include <iostream>
  4. #include <set>
  5. #include<random>
  6. #include <algorithm>
  7.  
  8. struct Point {
  9. long long x, y;
  10. Point() {
  11. x = 0;
  12. y = 0;
  13. }
  14. Point(long long a, long long b) {
  15. x = a;
  16. y = b;
  17. }
  18. };
  19. Point operator +(const Point pt1, const Point pt2) {
  20. return Point(pt1.x + pt2.x, pt1.y + pt2.y);
  21. }
  22.  
  23.  
  24. Point operator -(const Point pt1, const Point pt2) {
  25. return Point(pt1.x - pt2.x, pt1.y - pt2.y);
  26. }
  27.  
  28.  
  29. Point operator *(const Point pt, long long x) {
  30. return Point(pt.x * x, pt.y * x);
  31. }
  32.  
  33.  
  34. int operator *(const Point pt1, const Point pt2) {
  35. return pt1.x * pt2.x + pt1.y * pt2.y;
  36. }
  37.  
  38.  
  39. long long operator ^(const Point pt1, const Point pt2) {
  40. return pt1.x * pt2.y - pt1.y * pt2.x;
  41. }
  42.  
  43. bool AreEquel(Point pt1, Point pt2) {
  44. return pt1.x == pt2.x && pt1.y == pt2.y;
  45. }
  46.  
  47. struct Segment {
  48. Point one;
  49. Point two;
  50. Segment() {
  51. one = { 0, 0 };
  52. two = { 0, 0 };
  53. }
  54. Segment(Point x, Point y) {
  55. one = x;
  56. two = y;
  57. }
  58. Point less() {
  59. if (one.x < two.x || (one.x == two.x && one.y < two.y)) return one;
  60. return two;
  61. }
  62. Point more() {
  63. if (one.x < two.x || (one.x == two.x && one.y < two.y)) return two;
  64. return one;
  65. }
  66. };
  67.  
  68.  
  69. int Check(Segment* s, Point cur) {
  70. Segment t = *s;
  71. long long where_situated = ((cur - t.less()) ^ (t.more() - t.less()));
  72. if (where_situated > 0) return -1;
  73. if (where_situated == 0) return 0;
  74. return 1;
  75. }
  76.  
  77. bool CheckSegments(Segment* one, Segment* two) {
  78. Segment first = *one, second = *two;
  79. Point cur = second.less();
  80. long long where_situated = ((cur - first.less()) ^ (first.more() - first.less()));
  81. if (where_situated > 0) return true;
  82. if (where_situated == 0 && ((second.more() - cur) ^ (first.more() - first.less())) >= 0) return true;
  83. return false;
  84. }
  85.  
  86.  
  87. struct Event {
  88. int type;
  89. int num;
  90. Point p;
  91. };
  92.  
  93.  
  94. std::mt19937 rnd;
  95. int Mod = 1e9 + 7;
  96.  
  97.  
  98. class Cartesian_Tree {
  99. public:
  100. Cartesian_Tree() {
  101. root = Empty;
  102. }
  103.  
  104. void Insert(Segment *s) {
  105. Insert(root, s);
  106. }
  107.  
  108. void Erase(Point p) {
  109. Erase(root, p);
  110. }
  111.  
  112. int FindNumSegmentsMore(Point p) {
  113. return FindNumSegmentsMore(root, p, 0);
  114. }
  115.  
  116. private:
  117. struct node {
  118. node* left;
  119. node* right;
  120. Segment* key;
  121. int pr;
  122. int size;
  123. };
  124. node* Empty = new node{ NULL, NULL, NULL, 0, 0 };
  125. node* root;
  126.  
  127. void Update(node* &v) {
  128. v->size = v->left->size + v->right->size + 1;
  129. }
  130.  
  131. std::pair<node*, node*> Split(node* root, Segment* key) {
  132. if (root == Empty) return{ Empty, Empty };
  133. if (CheckSegments(root->key, key)) {
  134. std::pair<node*, node*> now = Split(root->left, key);
  135. root->left = now.second;
  136. Update(root);
  137. return{ now.first, root };
  138. }
  139. else {
  140. std::pair<node*, node*> now = Split(root->right, key);
  141. root->right = now.first;
  142. Update(root);
  143. return{ root, now.second };
  144. }
  145. }
  146.  
  147.  
  148. node* Merge(node* left, node* right) {
  149. if (left == Empty) return right;
  150. if (right == Empty) return left;
  151. if (left->pr < right->pr) {
  152. node* now = Merge(left->right, right);
  153. left->right = now;
  154. Update(now);
  155. Update(left);
  156. return left;
  157. }
  158. else {
  159. node* now = Merge(left, right->left);
  160. right->left = now;
  161. Update(now);
  162. Update(right);
  163. return right;
  164. }
  165. }
  166.  
  167.  
  168. void Insert(node* &root, Segment* s) {
  169. std::pair<node*, node*> now = Split(root, s);
  170. root = Merge(Merge(now.first, new node{ Empty, Empty, s, rand() % Mod, 1 }), now.second);
  171. }
  172.  
  173.  
  174. void Erase(node* &root, Point cur) {
  175. if (root == Empty) {
  176. return;
  177. }
  178. int where_situated = Check(root->key, cur);
  179. if (where_situated == 0) {
  180. root = Merge(root->left, root->right);
  181. return;
  182. }
  183. if (where_situated == -1) Erase(root->left, cur);
  184. else Erase(root->right, cur);
  185. Update(root);
  186. return;
  187. }
  188.  
  189.  
  190. int FindNumSegmentsMore(node*v, Point p, int cur_intersect) {
  191. if (v == Empty) return cur_intersect;
  192. int f = Check(v->key, p);
  193. if (f == 0) return -1;
  194. if (f == -1) { return FindNumSegmentsMore(v->left, p, cur_intersect); }
  195. return FindNumSegmentsMore(v->right, p, cur_intersect + v->left->size + 1);
  196. }
  197. };
  198.  
  199.  
  200. bool comp(Event one, Event two) {
  201. if (one.p.x < two.p.x) return true;
  202. if (one.p.x > two.p.x) return false;
  203. if (one.type < two.type) return true;
  204. if (one.type > two.type) return false;
  205. if (one.p.y < two.p.y) return true;
  206. if (one.p.y > two.p.y) return false;
  207. if (one.num < two.num) return true;
  208. return false;
  209. }
  210.  
  211.  
  212. class Solve {
  213. public:
  214. Solve() {
  215. count_of_vertex = 0;
  216. count_of_points = 0;
  217. e = 10000;
  218. polygon.resize(0);
  219. edge.resize(0);
  220. }
  221. void solution() {
  222. read();
  223. solve();
  224. write();
  225. }
  226.  
  227. private:
  228. int count_of_vertex;
  229. int count_of_points;
  230. long long e;
  231.  
  232. std::vector<Point> polygon;
  233. std::set<std::pair<int, int>> vertexs;
  234. std::vector<Segment> edge;
  235. std::vector<Point> points;
  236. std::vector<int> ans;
  237.  
  238. void add(Point cur) {
  239. if (polygon.size() > 0 && AreEquel(polygon.back(), cur)) return;
  240. if (polygon.size() > 0) {
  241. edge.push_back(Segment(polygon.back(), cur));
  242. }
  243. polygon.push_back(cur);
  244. vertexs.insert({ cur.x, cur.y });
  245. }
  246.  
  247. void ChangeEdge(int i) {
  248. Point cur = polygon[i];
  249. polygon[i] = { cur.x * e + cur.y, cur.y };
  250. vertexs.insert({ cur.x * e + cur.y, cur.y });
  251. if (i > 0) {
  252. edge.push_back({ polygon[i - 1], polygon[i] });
  253. }
  254. }
  255.  
  256.  
  257. void CheckEvent(Cartesian_Tree& tree, Event now) {
  258. //std::cout << now.type << ' ' << now.p.x << ' ' << now.p.y << ' ' << now.num << '\n';
  259. if (now.type == 0) {
  260. tree.Insert(&edge[now.num]);
  261. }
  262. if (now.type == -1) {
  263. tree.Erase(now.p);
  264. }
  265. if (now.type == 1) {
  266. if (vertexs.find({ now.p.x, now.p.y }) != vertexs.end()) {
  267. ans[now.num] = 0;
  268. return;
  269. }
  270. int intersections = tree.FindNumSegmentsMore(now.p);
  271. if (intersections == -1) {
  272. ans[now.num] = 0;
  273. }
  274. else {
  275. if (intersections % 2 == 0) {
  276. ans[now.num] = -1;
  277. }
  278. else {
  279. ans[now.num] = 1;
  280. }
  281. }
  282. }
  283. }
  284.  
  285. void read() {
  286. std::cin >> count_of_vertex;
  287. for (int i = 0; i < count_of_vertex; i++) {
  288. long long x, y;
  289. std::cin >> x >> y;
  290. Point cur = { x * e + y, y };
  291. add(cur);
  292. }
  293. if (AreEquel(polygon.back(), polygon[0])) {
  294. polygon.pop_back();
  295. }
  296. edge.push_back(Segment(polygon.back(), polygon[0]));
  297. count_of_vertex = polygon.size();
  298. std::cin >> count_of_points;
  299. points.resize(count_of_points);
  300. for (int i = 0; i < count_of_points; i++) {
  301. long long x, y;
  302. std::cin >> x >> y;
  303. Point cur = { x * e + y, y };
  304. points[i] = cur;
  305. }
  306. ans.resize(count_of_points);
  307. }
  308.  
  309. void solve() {
  310. std::vector<Event> events;
  311. for (int i = 0; i < count_of_vertex; i++) {
  312. events.push_back({ 0, i, edge[i].less() });
  313. events.push_back({ -1, i, edge[i].more() });
  314. }
  315. for (int i = 0; i < count_of_points; i++) {
  316. events.push_back({ 1, i, points[i] });
  317. }
  318. sort(events.begin(), events.end(), comp);
  319.  
  320. Cartesian_Tree tree = Cartesian_Tree();
  321. for (int i = 0; i < events.size(); i++) {
  322. CheckEvent(tree, events[i]);
  323. }
  324. }
  325.  
  326. void write() {
  327. for (int i = 0; i < count_of_points; i++) {
  328. if (ans[i] == -1) {
  329. std::cout << "OUTSIDE" << '\n';
  330. }
  331. if (ans[i] == 0) {
  332. std::cout << "BORDER" << '\n';
  333. }
  334. if (ans[i] == 1) {
  335. std::cout << "INSIDE" << '\n';
  336. }
  337. }
  338. }
  339. };
  340.  
  341.  
  342. int main() {
  343. int t;
  344. std::cin >> t;
  345. for (int i = 0; i < t; i++) {
  346. Solve solut = Solve();
  347. solut.solution();
  348. }
  349. system("pause");
  350. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement