zoukankan      html  css  js  c++  java
  • POJ 1436 Horizontally Visible Segments

    POJ_1436

        这个题目最后统计的时候直接暴力即可,一开始想的时候以为这样过不了的,没想到大家都是暴力统计的……而且我用“优化”后的局部O(nlogn)的统计方式(注释部分的代码),反倒没有局部O(n^2)的统计方式快,看来真正horizontally visible的线段对确实比较少。

        至于查询的过程,我们可以先把线段按x排序,然后逐一扫描,查询每个线段的下面还有哪些线段是可以“看得到”的,查询完之后再把线段所在的区间染色即可。

        此外,由于如果我们将每个纵坐标看作一个区间的话,这样两个相邻的纵坐标之间就没有空当了,所以为了避免丢解,可以把线段的坐标全部乘以2,这样奇数的坐标就表示了两个纵坐标之间的空当。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAXD 8010
    #define D 16000
    #define INF 0x3f3f3f3f
    #define MAXM 1000010
    struct Seg
    {
    int id, x, y1, y2;
    }seg[MAXD];
    int N, tree[8 * MAXD], to[8 * MAXD], a[MAXD], b[MAXD], A, B, e, first[MAXD], next[MAXM], v[MAXM], hash[MAXD];
    int cmpx(const void *_p, const void *_q)
    {
    Seg *p = (Seg *)_p, *q = (Seg *)_q;
    return p->x - q->x;
    }
    int cmpid(const void *_p, const void *_q)
    {
    int *p = (int *)_p, *q = (int *)_q;
    return *p - *q;
    }
    void pushdown(int cur)
    {
    int ls = cur << 1, rs = (cur << 1) | 1;
    if(to[cur] != -1)
    {
    to[ls] = to[rs] = to[cur];
    tree[ls] = tree[rs] = to[cur];
    to[cur] = -1;
    }
    }
    void update(int cur)
    {
    int ls = cur << 1, rs = (cur << 1) | 1;
    if(tree[ls] == tree[rs])
    tree[cur] = tree[ls];
    else
    tree[cur] = INF;
    }
    void build(int cur, int x, int y)
    {
    int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
    tree[cur] = to[cur] = -1;
    if(x == y)
    return ;
    build(ls, x, mid);
    build(rs, mid + 1, y);
    }
    void init()
    {
    int i;
    scanf("%d", &N);
    for(i = 0; i < N; i ++)
    {
    scanf("%d%d%d", &seg[i].y1, &seg[i].y2, &seg[i].x);
    seg[i].id = i;
    }
    build(1, 0, D);
    qsort(seg, N, sizeof(seg[0]), cmpx);
    }
    void query(int cur, int x, int y, int s, int t, int id)
    {
    int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
    if(x >= s && y <= t)
    {
    if(tree[cur] != INF)
    {
    if(tree[cur] != -1 && hash[tree[cur]] != id)
    {
    hash[tree[cur]] = id;
    v[e] = tree[cur];
    next[e] = first[id];
    first[id] = e;
    ++ e;
    }
    return ;
    }
    }
    pushdown(cur);
    if(mid >= s)
    query(ls, x, mid, s, t, id);
    if(mid + 1 <= t)
    query(rs, mid + 1, y, s, t, id);
    }
    void color(int cur, int x, int y, int s, int t, int c)
    {
    int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
    if(x >= s && y <= t)
    {
    tree[cur] = to[cur] = c;
    return ;
    }
    pushdown(cur);
    if(mid >= s)
    color(ls, x, mid, s, t, c);
    if(mid + 1 <= t)
    color(rs, mid + 1, y, s, t, c);
    update(cur);
    }
    void solve()
    {
    int i, j, k, l, ra, rb, ans = 0;
    e = 0;
    memset(hash, -1, sizeof(hash[0]) * N);
    memset(first, -1, sizeof(first[0]) * N);
    for(i = 0; i < N; i ++)
    {
    query(1, 0, D, seg[i].y1 << 1, seg[i].y2 << 1, seg[i].id);
    color(1, 0, D, seg[i].y1 << 1, seg[i].y2 << 1, seg[i].id);
    }
    for(i = 0; i < N; i ++)
    for(j = first[i]; j != -1; j = next[j])
    for(k = first[i]; k != -1; k = next[k])
    for(l = first[v[j]]; l != -1; l = next[l])
    if(v[k] == v[l])
    ++ ans;
    /*
    for(i = 0; i < N; i ++)
    {
    A = 0;
    for(k = first[i]; k != -1; k = next[k])
    a[A ++] = v[k];
    qsort(a, A, sizeof(a[0]), cmpid);
    for(j = 0; j < A; j ++)
    {
    B = 0;
    for(k = first[a[j]]; k != -1; k = next[k])
    b[B ++] = v[k];
    qsort(b, B, sizeof(b[0]), cmpid);
    for(ra = rb = 0; ra < A && rb < B;)
    {
    if(a[ra] == b[rb])
    ++ ans;
    if(a[ra] <= b[rb])
    ++ ra;
    else
    ++ rb;
    }
    }
    }
    */
    printf("%d\n", ans);
    }
    int main()
    {
    int t;
    scanf("%d", &t);
    while(t --)
    {
    init();
    solve();
    }
    return 0;
    }


  • 相关阅读:
    Js设计模式之:单例模式
    javascript中的匿名方法(函数)是什么?
    JavaScript 模块化简析
    JavaScript V8 Object 内存结构与属性访问详解
    JavaScript 开发者应该知道的 setTimeout 秘密
    JavaScript 函数式编程导论
    javascript中如何实现继承?
    关于token你需要知道的【华为云技术分享】
    移动端开发语言的未来的猜想#华为云&#183;寻找黑马程序员#【华为云技术分享】
    MySQL数据库开发的36条原则【华为云技术分享】
  • 原文地址:https://www.cnblogs.com/staginner/p/2435045.html
Copyright © 2011-2022 走看看