Advertisement
Guest User

D06_B Mountainous Landscape

a guest
Nov 27th, 2015
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.42 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <cmath>
  4. #include <vector>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. #pragma warning (disable : 4996)
  10.  
  11. vector<int> ans;
  12. typedef pair<long long, long long> point;
  13. vector<point> vp;
  14. int n;
  15.  
  16. #define EPS 1e-6
  17.  
  18. //cross product of (ab), (cd)
  19. long long cross(point a, point b, point c, point d) {
  20.     point ab = { b.first - a.first, b.second - a.second };
  21.     point cd = { d.first - c.first, d.second - c.second };
  22.     return ab.first * cd.second - ab.second * cd.first;
  23. }
  24.  
  25. int sign(long long val) {
  26.     return (val == 0 ? 0 : (val < 0 ? -1 : 1));
  27. }
  28.  
  29. point operator - (point & a, point & b) {
  30.     point r = { b.first - a.first, b.second - a.second };
  31.     return r;
  32. }
  33.  
  34. //segment tree of convex hulls
  35. struct tree {
  36.     vector<vector<point>> data;
  37.     int n;
  38.     tree() {}
  39.     tree(int n, vector<point> & v) : n(n) {
  40.         data.resize(n * 8 + 100);
  41.         build(v);
  42.     }
  43.     void build(vector<point> & v) {
  44.         build(v, 0, 0, n - 1);
  45.     }
  46.     void build(vector<point> & v, int i, int cl, int cr) {
  47.         if (cl >= cr)
  48.             return;
  49.         if (cl == cr) {
  50.             data[i].push_back(v[cl]);
  51.             return;
  52.         }
  53.         if (cl == cr - 1) {
  54.             data[i].push_back(v[cl]);
  55.             data[i].push_back(v[cr]);
  56.             return;
  57.         }
  58.         for (int j = cl; j <= cr; j++) {
  59.             int t;
  60.             while (t = data[i].size(), t > 1 && (cross(data[i][t - 2], v[j], data[i][t - 2], data[i][t - 1]) < 0))
  61.                 data[i].pop_back();
  62.             data[i].push_back(v[j]);
  63.         }
  64.         int m = (cl + cr) >> 1;
  65.         build(v, i * 2 + 1, cl, m);
  66.         build(v, i * 2 + 2, m, cr);
  67.     }
  68.     bool ok(point a, point b, point c, point d) {
  69.         point ab = b - a;
  70.         point ac = c - a;
  71.         point ad = d - a;
  72.         if (cross(a, b, a, c) <= 0 && cross(a, b, a, d) > 0)
  73.             return true;
  74.         return false;
  75.     }
  76.     int get_ans(int i, int cl, int cr, point a, point b, int l, int r) {
  77.         if (r < cl || l > cr)
  78.             return -1;
  79.         if (cl > cr || l > r)
  80.             return -1;
  81.         if (cl == cr - 1) {
  82.             if (ok(a, b, vp[cl], vp[cr])) {
  83.                 return cl;
  84.             }
  85.             else {
  86.                 return -1;
  87.             }
  88.         }
  89.         int m = (cl + cr) >> 1;
  90.         if (cl >= l && cr <= r) {
  91.             if (can_see(a, b, data[2 * i + 1], l)) {
  92.                 int t = get_ans(2 * i + 1, cl, m, a, b, l, min(r, m));
  93.                 if (t != -1)
  94.                     return t;
  95.             }
  96.             if (can_see(a, b, data[2 * i + 2], l)) {
  97.                 return get_ans(2 * i + 2, m, cr, a, b, max(l, m), r);
  98.             }
  99.         }
  100.         else {
  101.             if (l <= m) {
  102.                 int t = get_ans(2 * i + 1, cl, m, a, b, l, min(r, m));
  103.                 if (t != -1)
  104.                     return t;
  105.             }
  106.             if (r >= m) {
  107.                 int t = get_ans(2 * i + 2, m, cr, a, b, max(l, m), r);
  108.                 if (t != -1)
  109.                     return t;
  110.             }
  111.             return -1;
  112.         }
  113.         return -1;
  114.     }
  115.     int get_ans(int i) {
  116.         int ans = -1;
  117.         ans = get_ans(0, 0, n - 1, vp[i], vp[i + 1], i + 2, n - 1);
  118.         return ans;
  119.     }
  120.     bool can_see(point a, point b, vector<point> const & v, int k) {
  121.         if (v.size() == 1)
  122.             return false;
  123.         int st, fin;
  124.         int l = 0, r = v.size() - 1;
  125.         while (l < r && v[l].first < vp[k - 1].first)
  126.             l++;
  127.         if (l == r)
  128.             return false;
  129.         st = l, fin = r;
  130.         double ang = atan2(b.second - a.second, b.first - a.first);
  131.         double last_ang = atan2(v[r].second - v[r - 1].second, v[r].first - v[r - 1].first);
  132.         double first_ang = atan2(v[l + 1].second - v[l].second, v[l + 1].first - v[l].first);
  133.         if (last_ang >= ang || first_ang <= ang) {
  134.             int x1 = sign(cross(a, b, a, v[l]));
  135.             int x2 = sign(cross(a, b, a, v[r]));
  136.             return (x1 <= 0 && x2 > 0);
  137.         }
  138.         while (l < r - 1) {
  139.             int m = (l + r) >> 1;
  140.             double cang = atan2(v[m + 1].second - v[m].second, v[m + 1].first - v[m].first);
  141.             if (cang < ang || abs(cang - ang) < EPS)
  142.                 r = m;
  143.             else
  144.                 l = m;
  145.         }
  146.         int x1 = min(sign(cross(a, b, a, v[st])), sign(cross(a, b, a, v[fin])));
  147.         int x2 = sign(cross(a, b, a, v[r]));
  148.         return (x1 <= 0 && x2 > 0);
  149.     }
  150. };
  151.  
  152. tree tr;
  153.  
  154. void solve() {
  155.     //when next segment is visible
  156.     for (int j = n - 3; j >= 0; j--) {
  157.         if (cross(vp[j], vp[j+1], vp[j+1], vp[j + 2]) > 0) {
  158.             ans[j] = j + 1;
  159.         }
  160.     }
  161.     tr = tree(n, vp);
  162.     for (int j = n - 3; j >= 0; j--) {
  163.         if (ans[j] == -1) {
  164.             int e = tr.get_ans(j);
  165.             ans[j] = e;
  166.         }
  167.     }
  168. }
  169.  
  170. int main() {
  171. #ifdef _DEBUG
  172.     freopen("input.txt", "r", stdin);
  173.     freopen("output.txt", "w", stdout);
  174. #endif
  175.     int T;
  176.     cin >> T;
  177.     while (T--) {
  178.         cerr << T << endl;
  179.         cin >> n;
  180.         vp.resize(n);
  181.         ans.assign(n - 1, -1);
  182.         for (int i = 0; i < n; i++) {
  183.             scanf("%d%d", &vp[i].first, &vp[i].second);
  184.         }
  185.         solve();
  186.         for (int i = 0; i < n - 1; i++) {
  187.             printf("%d ", ans[i] + 1);
  188.         }
  189.         printf("\n");
  190.     }
  191.     return 0;
  192. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement