Advertisement
Guest User

Untitled

a guest
Nov 12th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.36 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. struct point
  6. {
  7. long long x, y, ind;
  8. };
  9.  
  10. struct segment
  11. {
  12. point left, right;
  13. };
  14.  
  15. long long triangle_area (point a, point b, point c)
  16. {
  17. return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
  18. }
  19.  
  20. bool clockwise (point a, point b, point c) {
  21. return triangle_area (a, b, c) <= 0;
  22. }
  23.  
  24. bool counter_clockwise (point a, point b, point c) {
  25. return triangle_area (a, b, c) >= 0;
  26. }
  27.  
  28. bool is_under(point z, segment a)
  29. {
  30. if (z.x < a.left.x || z.x > a.right.x)
  31. return false;
  32. return counter_clockwise(z, a.right, a.left);
  33. }
  34.  
  35. bool is_above(point z, segment a)
  36. {
  37. if (z.x < a.left.x || z.x > a.right.x)
  38. return false;
  39. return clockwise(z, a.right, a.left);
  40. }
  41.  
  42. bool in_segment(point z, segment a)
  43. {
  44. return is_above(z, a) && is_under(z, a);
  45. }
  46.  
  47. bool cmp_x(point & a, point & b)
  48. {
  49. return a.x < b.x || a.x == b.x && a.y < b.y;
  50. }
  51.  
  52. bool cmp_seg(segment & a, segment & b)
  53. {
  54. return a.left.x < b.left.x || a.left.x == b.left.x && a.right.x < b.right.x;
  55. }
  56.  
  57. bool is_equal(segment a, segment b)
  58. {
  59. return (a.left.x == b.left.x && a.left.y == b.left.y && a.right.x == b.right.x && a.right.y == b.right.y);
  60. }
  61.  
  62. bool cmp_pair(pair <point, int> & a, pair < point, int> & b)
  63. {
  64. if (a.first.x < b.first.x)
  65. return true;
  66. if (a.first.x > b.first.x)
  67. return false;
  68. int a_sec = a.second;
  69. int b_sec = b.second;
  70. if (a_sec >= 0)
  71. a_sec %= 2;
  72. if (b_sec >= 0)
  73. b_sec %=2;
  74. if (a_sec != b_sec)
  75. return b_sec < a_sec;
  76. return (a.first.y < b.first.y);
  77. }
  78.  
  79. bool is_under(segment a, segment b)
  80. {
  81. if (a.left.x == b.left.x)
  82. {
  83. if (a.left.y != b.left.y)
  84. return a.left.y < b.left.y;
  85. return (is_under(a.right, b) || is_above(b.right, a));
  86. }
  87. if (a.right.x == b.right.y)
  88. {
  89. if (a.right.y != b.right.y)
  90. return a.right.y < b.right.y;
  91. return(is_under(a.left, b) || is_above(b.left, a));
  92.  
  93. }
  94. return (is_under(a.left, b) || is_under(a.right, b) ||
  95. is_above(b.left, a) || is_above(b.right, a));
  96. }
  97.  
  98. bool is_above(segment a, segment b)
  99. {
  100. if (a.left.x == b.left.x)
  101. {
  102. if (a.left.y != b.left.y)
  103. return a.left.y > b.left.y;
  104. return (is_above(a.right, b) || is_under(b.right, a));
  105. }
  106. if (a.right.x == b.right.y)
  107. {
  108. if (a.right.y != b.right.y)
  109. return a.right.y > b.right.y;
  110. return(is_above(a.left, b) || is_under(b.left, a));
  111. }
  112. return (is_above(a.left, b) || is_above(a.right, b) ||
  113. is_under(b.left, a) || is_under(b.right, a));
  114. }
  115.  
  116. int n;
  117. const int MAXN = 1e5+1e3;
  118. const long long INF = 2*1e18 + 1e9;
  119. segment segments[MAXN];
  120. string ans[MAXN];
  121.  
  122. //treap
  123.  
  124. //###########################################################################
  125.  
  126. struct Node {
  127. int key, sz, val;
  128. Node *l, *r;
  129. };
  130.  
  131. Node* root;
  132.  
  133. Node* new_node(int val)
  134. {
  135. Node *result = new Node;
  136. result->key = rand();
  137. result->sz = 1;
  138. result->val = val;
  139. result->l = result->r = nullptr;
  140. return result;
  141. }
  142.  
  143. int get_sz(Node *t)
  144. {
  145. if (t == nullptr) { return 0; }
  146. return t->sz;
  147. }
  148.  
  149. void upd_sz(Node *t)
  150. {
  151. if (t == nullptr) { return; }
  152. t->sz = 1 + get_sz(t->l) + get_sz(t->r);
  153. }
  154.  
  155. Node *merge(Node* t1, Node *t2)
  156. {
  157. if (t1 == nullptr) { return t2; }
  158. if (t2 == nullptr) { return t1; }
  159. if (t1->key > t2->key)
  160. {
  161. t1->r = merge(t1->r, t2);
  162. upd_sz(t1);
  163. return t1;
  164. }
  165. else
  166. {
  167. t2->l = merge(t1, t2->l);
  168. upd_sz(t2);
  169. return t2;
  170. }
  171. }
  172.  
  173. void split(Node *t, int x, Node *&t1, Node *&t2)
  174. {
  175. if (t == nullptr)
  176. {
  177. t1 = t2 = nullptr;
  178. return;
  179. }
  180. if (get_sz(t->l) < x)
  181. {
  182. split(t->r, x - get_sz(t->l) - 1, t->r, t2);
  183. t1 = t;
  184. }
  185. else
  186. {
  187. split(t->l, x, t1, t->l);
  188. t2 = t;
  189. }
  190. upd_sz(t);
  191. }
  192.  
  193. Node *add(Node *t, int pos, int val)
  194. {
  195. Node *t1, *t2;
  196. split(t, pos, t1, t2);
  197. Node* new_tree = new_node(val);
  198. return merge(merge(t1, new_tree), t2);
  199. }
  200.  
  201. Node* erase(Node *t, int pos)
  202. {
  203. cout << get_sz(root) << " 77777777\n";
  204.  
  205. Node *t1, *t2, *t3, *t4;
  206. split(t, pos, t1, t2);
  207. split(t2, pos + 1, t3, t4);
  208. t = merge(t1, t4);
  209. delete t3;
  210. return t;
  211. }
  212.  
  213. int get(Node *t, int pos)
  214. {
  215. int my_idx = get_sz(t->l);
  216. if (pos < my_idx)
  217. {
  218. return get(t->l, pos);
  219. }
  220. else if (pos == my_idx)
  221. {
  222. return t->val;
  223. }
  224. else
  225. {
  226. return get(t->r, pos - my_idx - 1);
  227. }
  228. }
  229.  
  230.  
  231. //#####################################################################
  232.  
  233. void add_segment(int ind)
  234. {
  235. int sz = get_sz(root);
  236. if (sz == 1)
  237. {
  238. segment seg = segments[get(root, 0)];
  239. if (is_under(segments[ind], seg))
  240. root = add(root, 0, ind);
  241. else
  242. root = add(root, 1, ind);
  243. return;
  244. }
  245.  
  246. if (sz == 0)
  247. {
  248. root = add(root, 0, ind);
  249. return;
  250. }
  251.  
  252. int l = 0; int r = sz - 1;
  253.  
  254. segment l_seg = segments[get(root, l)];
  255. segment r_seg = segments[get(root, r)];
  256. if (is_under(segments[ind], l_seg))
  257. {
  258. root = add(root, 0, ind);
  259. return;
  260. }
  261. if (is_above(segments[ind], r_seg))
  262. {
  263. root = add(root, r + 1, ind);
  264. return;
  265. }
  266. while (l < r - 1)
  267. {
  268. int md = (l + r) / 2;
  269. segment md_seg = segments[get(root, md)];
  270. if (is_under(segments[ind], md_seg))
  271. r = md;
  272. else
  273. l = md;
  274. }
  275. root = add(root, l + 1, ind);
  276. }
  277.  
  278.  
  279. void delete_segment(int ind)
  280. {
  281. //cout << get_sz(root) << " 77777777\n";
  282. if(get_sz(root) == 1)
  283. {
  284. root = erase(root, 0);
  285. return;
  286. }
  287. int l = 0; int r = get_sz(root) - 1;
  288.  
  289. segment l_seg = segments[get(root, 0)];
  290. segment r_seg = segments[get(root, r)];
  291.  
  292. if (is_equal(segments[ind], l_seg))
  293. {
  294. root = erase(root, 0);
  295. return;
  296. }
  297.  
  298. if (is_equal(segments[ind], r_seg))
  299. {
  300. root = erase(root, r);
  301. return;
  302. }
  303.  
  304. while (l < r - 1)
  305. {
  306. int md = (l + r) / 2;
  307. segment md_seg = segments[get(root, md)];
  308. if (is_under(segments[ind], md_seg))
  309. r = md;
  310. else
  311. l = md;
  312. }
  313. r_seg = segments[get(root, r)];
  314. if (is_equal(segments[ind], r_seg))
  315. {
  316. root = erase(root, r);
  317. return;
  318. }
  319. root = erase(root, l);
  320.  
  321. }
  322.  
  323.  
  324. int fnd_inter_cnt(point x)
  325. {
  326. if (get_sz(root) == 0)
  327. return 0;
  328. int l = 0; int r = get_sz(root) - 1;
  329. int sz = r + 1;
  330.  
  331.  
  332. cout << sz << '\n';
  333. cout << "point x:" << x.x << ' ' << x.y <<'\n';
  334. point lf = segments[get(root, l)].left;
  335. point rf = segments[get(root, l)].right;
  336. cout << "first segment" << lf.x << ' ' << lf.y << ' ' << rf.x << ' ' << rf.y << '\n';
  337. lf = segments[get(root, r)].left;
  338. rf = segments[get(root, r)].right;
  339. cout << "second segment" << lf.x << ' ' << lf.y << ' ' << rf.x << ' ' << rf.y << '\n';
  340. cout << "######\n";
  341.  
  342.  
  343. if (!is_under(x, segments[get(root, r)]) || !is_above(x, segments[get(root, l)]))
  344. return 0;
  345. while (l < r - 1)
  346. {
  347. int md = (l + r) / 2;
  348. segment md_seg = segments[get(root, md)];
  349. if (is_above(x, md_seg))
  350. l = md;
  351. else
  352. r = md;
  353. }
  354. //cout << "here\n";
  355. if (in_segment(x, segments[get(root, l)]) || in_segment(x, segments[get(root, r)]))
  356. return -1;
  357. return sz - r;
  358.  
  359. }
  360.  
  361.  
  362. void affine_transformation(vector<point>* v, int a, int b, int c, int d)
  363. {
  364. for (int i = 0; i < (*v).size(); i++)
  365. {
  366. long long x = (*v)[i].x, y = (*v)[i].y;
  367. (*v)[i].x = a * x + b * y;
  368. (*v)[i].y = c * x + d * y;
  369. }
  370. }
  371.  
  372. void fnd_locations(vector <point> queries)
  373. {
  374.  
  375. vector <pair < point, int > > points;
  376. for (int i = 0; i < n; i++)
  377. {
  378. points.push_back({segments[i].left, 2 * i});
  379. points.push_back({segments[i].right, 2 * i + 1});
  380. }
  381. int k = queries.size();
  382. for (int i = 0; i < k; i++)
  383. points.push_back({queries[i], -1});
  384.  
  385. sort(points.begin(), points.end(), &cmp_pair);
  386. /*
  387. for (int i = 0; i < points.size(); i++)
  388. {
  389. cout << points[i].first.x << ' ' << points[i].first.y << ' ' << points[i].second << '\n';
  390. }
  391. */
  392.  
  393. for (int i = 0; i < points.size(); i++)
  394. {
  395. auto cur = points[i];
  396. if (cur.second == -1)
  397. {
  398. int inter_cnt = fnd_inter_cnt(cur.first);
  399. if (inter_cnt % 2 == 1)
  400. ans[cur.first.ind] = "INSIDE";
  401. if (inter_cnt % 2 == 0)
  402. ans[cur.first.ind] = "OUTSIDE";
  403. if (inter_cnt == -1)
  404. ans[cur.first.ind] = "BORDER";
  405. }
  406. if (cur.second != -1 && cur.second % 2 == 0)
  407. {
  408. add_segment(cur.second / 2);
  409. }
  410. if (cur.second != -1 && cur.second % 2 == 1)
  411. {
  412. delete_segment(cur.second / 2);
  413. }
  414. }
  415. }
  416.  
  417.  
  418. int solve()
  419. {
  420. root = nullptr;
  421. cin >> n;
  422. vector<point> v;
  423. for (int i = 0; i < n; i++)
  424. {
  425. int x, y;
  426. cin >> x >> y;
  427. v.push_back({x, y, i});
  428. }
  429. int k;
  430. cin >> k;
  431. vector <point> queries;
  432. for (int i = 0; i < k; i++)
  433. {
  434. int x, y;
  435. cin >> x >> y;
  436. queries.push_back({x, y, i});
  437. }
  438.  
  439. affine_transformation(&v, 1, 1, 0, 1);
  440. affine_transformation(&queries, 1, 1, 0, 1);
  441.  
  442. //sort(queries.begin(), queries.end(), &cmp_x);
  443. for (int i = 0; i < n - 1; i++)
  444. {
  445. if (v[i].x < v[i + 1].x || v[i].x == v[i + 1].x && v[i].y < v[i + 1].y)
  446. segments[i] = {v[i], v[i + 1]};
  447. else
  448. segments[i] = {v[i + 1], v[i]};
  449. }
  450.  
  451. if (v[0].x < v[n - 1].x || v[0].x == v[n - 1].x && v[0].y < v[n - 1].y)
  452. segments[n - 1] = {v[0], v[n - 1]};
  453. else
  454. segments[n - 1] = {v[n - 1], v[0]};
  455. //sort(segments, segments + n, &cmp_seg);
  456. fnd_locations(queries);
  457. for (int i = 0; i < k; i++)
  458. cout << ans[i] <<'\n';
  459.  
  460. }
  461.  
  462.  
  463. int main()
  464. {
  465. int t;
  466. cin >> t;
  467. while (t > 0)
  468. {
  469. t--;
  470. solve();
  471. cout <<'\n';
  472. }
  473. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement