zoukankan      html  css  js  c++  java
  • BZOJ4049 [Cerc2014] Mountainous landscape

    首先对于一个给定的图形,要找到是否存在答案非常简单。。。

    只要维护当然图形的凸包,看一下是否有线段在这条直线上方,直接二分即可,单次询问的时间复杂度$O(logn)$

    现在用线段树维护凸包,即对于一个区间$[l, r]$,我们维护点$[P_l, P_{r +1}]$形成的凸包

    于是每次查询只要在线段树上二分,总复杂度$O(nlogn + nlog^2n)$(建树 + 查询)

      1 /**************************************************************
      2     Problem: 4049
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:5052 ms
      7     Memory:73960 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <vector>
     12  
     13 using namespace std;
     14 typedef long long ll;
     15 const int N = 1e5 + 5;
     16  
     17 int read();
     18  
     19 int n;
     20  
     21 struct point {
     22     int x, y;
     23     point(int _x, int _y) : x(_x), y(_y) {}
     24     point() {}
     25      
     26     inline point operator + (const point &p) const {
     27         return point(x + p.x, y + p.y);
     28     }
     29     inline point operator - (const point &p) const {
     30         return point(x - p.x, y - p.y);
     31     }
     32     inline ll operator * (const point &p) const {
     33         return 1ll * x * p.y - 1ll * y * p.x;
     34     }
     35      
     36     inline void get() {
     37         x = read(), y = read();
     38     }
     39      
     40     friend inline ll calc(const point &a, const point &b, const point &c) {
     41         return (a - b) * (c - b);
     42     }
     43 } p[N];
     44  
     45 struct convex {
     46     vector <point> s;
     47      
     48     inline void clear() {
     49         s.clear();
     50     }
     51     #define top ((int) s.size() - 1)
     52     inline void insert(const point &p) {
     53         while (top > 0 && calc(p, s[top - 1], s[top]) <= 0) s.pop_back();
     54         s.push_back(p);
     55     }
     56      
     57     #define mid (l + r >> 1)
     58     inline bool query(const point &p, const point &q) {
     59         int l = 0, r = top - 1;
     60         while (l < r) {
     61             if (calc(s[mid], p, q) < calc(s[mid + 1], p, q)) r = mid;
     62             else l = mid + 1;
     63         }
     64         return calc(s[l], p, q) < 0 || calc(s[l + 1], p, q) < 0;
     65     }
     66     #undef mid
     67     #undef top
     68 };
     69  
     70 struct seg {
     71     seg *ls, *rs;
     72     convex c;
     73      
     74     #define Len (1 << 16)
     75     inline void* operator new(size_t, int f = 0) {
     76         static seg mempool[N << 2], *c;
     77         if (f) c = mempool;
     78         c -> ls = c -> rs = NULL, c -> c.clear();
     79         return c++;
     80     }
     81     #undef Len
     82      
     83     #define mid (l + r >> 1)
     84     void build(int l, int r) {
     85         int i;
     86         for (i = l; i <= r + 1; ++i) c.insert(p[i]);
     87         if (l == r) return;
     88         (ls = new()seg) -> build(l, mid);
     89         (rs = new()seg) -> build(mid + 1, r);
     90     }
     91      
     92     int query(int l, int r, int L, int R, const point &p, const point &q) {
     93         if (R < l || r < L) return 0;
     94         if (L <= l && r <= R) {
     95             if (!c.query(p, q)) return 0;
     96             if (l == r) return l;
     97         }
     98         int res = ls -> query(l, mid, L, R, p, q);
     99         return res ? res : rs -> query(mid + 1, r, L, R, p, q);
    100     }
    101     #undef mid
    102 } *T;
    103  
    104 int main() {
    105     int Tmp, i;
    106     for (Tmp = read(); Tmp; --Tmp) {
    107         n = read();
    108         for (i = 1; i <= n; ++i) p[i].get();
    109         (T = new(1)seg) -> build(1, n - 1);
    110         for (i = 1; i < n - 1; ++i)
    111             printf("%d ", T -> query(1, n - 1, i + 1, n - 1, p[i], p[i + 1]));
    112         puts("0");
    113     }
    114     return 0;
    115 }
    116  
    117 inline int read() {
    118     static int x;
    119     static char ch;
    120     x = 0, ch = getchar();
    121     while (ch < '0' || '9' < ch)
    122         ch = getchar();
    123     while ('0' <= ch && ch <= '9') {
    124         x = x * 10 + ch - '0';
    125         ch = getchar();
    126     }
    127     return x;
    128 }
    View Code
  • 相关阅读:
    C# DateTime
    C# const static readonly
    HTML div+CSS
    javaScript 正则表达式验证
    前期绑定和后期绑定
    如何应对大数据量高并发访问问题
    数据库优化之:SQL语句优化之二
    银河系漫游指南 图标
    [转] 花3分钟时间来关闭你电脑上没用的服务
    Devdays 2006 China 微软开发者日
  • 原文地址:https://www.cnblogs.com/rausen/p/4528869.html
Copyright © 2011-2022 走看看