zoukankan      html  css  js  c++  java
  • poj 1436 && zoj 1391 Horizontally Visible Segments (Segment Tree)

    ZOJ :: Problems :: Show Problem

    1436 -- Horizontally Visible Segments

      用线段树记录表面能被看见的线段的编号,然后覆盖的时候同时把能看到的线段记录下来。这里要用到拆点,在两个整点之间插入一个点。

      最后O(n^2)统计三角形的个数,因为每条线段可以看见的另外的线段的条数不多,所以可以直接枚举两条边。

    代码如下:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <set>
     6 
     7 using namespace std;
     8 
     9 const int N = 16666;
    10 #define lson l, m, rt << 1
    11 #define rson m + 1, r, rt << 1 | 1
    12 #define root 0, 16000, 1
    13 int cov[N << 2];
    14 
    15 void up(int rt) {
    16     if (~cov[rt << 1] && cov[rt << 1] == cov[rt << 1 | 1]) cov[rt] = cov[rt << 1];
    17     else cov[rt] = -1;
    18 }
    19 
    20 void down(int rt) { if (~cov[rt]) cov[rt << 1] = cov[rt << 1 | 1] = cov[rt];}
    21 
    22 void build(int L, int R, int l, int r, int rt) {
    23     if (l >= r) {
    24         cov[rt] = L <= l && r <= R ? 1 : 0;
    25         return ;
    26     }
    27     int m = l + r >> 1;
    28     build(L, R, lson);
    29     build(L, R, rson);
    30     up(rt);
    31 }
    32 
    33 set<int> edge[N >> 1];
    34 
    35 void update(int k, int L, int R, int l, int r, int rt) {
    36     if (L <= l && r <= R && ~cov[rt]) {
    37         if (cov[rt]) edge[k].insert(cov[rt]);
    38         cov[rt] = k;
    39         return ;
    40     }
    41     int m = l + r >> 1;
    42     down(rt);
    43     if (L <= m) update(k, L, R, lson);
    44     if (m < R) update(k, L, R, rson);
    45     up(rt);
    46 }
    47 
    48 struct Node {
    49     int l, r, p;
    50 } seg[N >> 1];
    51 
    52 bool cmp(Node a, Node b) { return a.p < b.p;}
    53 
    54 int main() {
    55 //    freopen("in", "r", stdin);
    56     int T, n;
    57     scanf("%d", &T);
    58     while (T-- && ~scanf("%d", &n)) {
    59         for (int i = 1; i <= n; i++) {
    60             scanf("%d%d%d", &seg[i].l, &seg[i].r, &seg[i].p);
    61             seg[i].l <<= 1, seg[i].r <<= 1;
    62         }
    63         sort(seg + 1, seg + n + 1, cmp);
    64         edge[1].clear();
    65         build(seg[1].l, seg[1].r, root);
    66         for (int i = 2; i <= n; i++) {
    67             edge[i].clear();
    68             update(i, seg[i].l, seg[i].r, root);
    69         }
    70         set<int>::iterator si, sj;
    71         int ans = 0;
    72         for (int i = 1; i <= n; i++) {
    73 //            cout << i << " : ";
    74 //            for (si = edge[i].begin(); si != edge[i].end(); si++) cout << *si << ' ';
    75 //            cout << endl;
    76             for (si = edge[i].begin(); si != edge[i].end(); si++) {
    77                 int t = *si;
    78                 for (sj = edge[i].begin(); sj != edge[i].end(); sj++) {
    79                     ans += edge[t].find(*sj) != edge[t].end();
    80                 }
    81             }
    82         }
    83         printf("%d
    ", ans);
    84     }
    85     return 0;
    86 }
    View Code

    ——written by Lyon

  • 相关阅读:
    ElasticSearch的高级复杂查询:非聚合查询和聚合查询
    js上传文件前判断获取文件大小并且加以判断
    如何使用IE9浏览器自带开发人员工具捕获网页请求
    目标的滚动条样式设置
    springmvc配置数据源方式
    SSO单点登录一:cas单点登录防止登出退出后刷新后退ticket失效报500错,也有退出后直接重新登录报票根验证错误
    解决myeclipse中新建javaweb工程,无法使用Web App Libraries问题
    敏捷宣言(十七)
    敏捷宣言(十六)
    敏捷宣言(十五)
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_1436_zoj_1391_Lyon.html
Copyright © 2011-2022 走看看