zoukankan      html  css  js  c++  java
  • POJ1436 线段树 区间更新

    题中定义了什么叫做可见线段。所谓可见线段就是在给定的垂直与x轴的直线中,能够在两个直线之间连接一条平行线,并且这条平行线不与任何其他的直线相交。

    WA一次,就是因为没有考虑到在建立点树的过程中会出现将 [1, 2] 和 [3, 4] 视为一条连接的直线,所以最后给坐标乘以一个2.

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    #include <map>
    #define MAXN 8000
    using namespace std;

    struct Seq
    {
    int y1, y2, x;
    bool operator < (Seq t) const
    {
    return x < t.x;
    }
    }e[MAXN+5];

    struct
    {
    int l, r, who;
    }seg[MAXN*8];

    map<int,int>m[MAXN+5];

    void build(int f, int l, int r)
    {
    int mid = l+r >> 1;
    seg[f].l = l, seg[f].r = r;
    seg[f].who = 0;
    if (r > l)
    {
    build(f<<1, l, mid);
    build(f<<1|1, mid+1, r);
    }
    }

    void up(int f)
    {
    if (seg[f<<1].who == seg[f<<1|1].who)
    seg[f].who = seg[f<<1].who;
    else
    seg[f].who = -1;
    }

    void modify(int f, int l, int r, int who, map<int, int>*m)
    {
    int mid = seg[f].l+seg[f].r >> 1;
    if (seg[f].l == l && seg[f].r == r && (seg[f].who != -1 || r==l))
    {
    if (seg[f].who != -1 && seg[f].who != 0)
    m[who][seg[f].who] = 1;
    seg[f].who = who;

    }
    else if (seg[f].r > seg[f].l)
    {
    if (seg[f].who == 0)
    {
    seg[f<<1].who = seg[f<<1|1].who = seg[f].who;
    seg[f].who = -1;
    }
    else if (seg[f].who != -1)
    {
    m[who][seg[f].who] = 1;
    seg[f<<1].who = seg[f<<1|1].who = seg[f].who;
    seg[f].who = -1;
    }
    if (r <= mid)
    modify(f<<1, l, r, who, m);
    else if (l > mid)
    modify(f<<1|1, l, r, who, m);
    else
    {
    modify(f<<1, l, mid, who, m);
    modify(f<<1|1, mid+1, r, who, m);
    }
    up(f);
    }
    }

    int main()
    {
    map<int,int>::iterator it1, it2;
    int T, M, y1, y2, x, ans;
    scanf("%d", &T);
    build(1, 0, 2*MAXN);
    while (T--)
    {
    ans = 0;
    seg[1].who = 0;
    scanf("%d", &M);
    for (int i = 1; i <= M; ++i)
    {
    scanf("%d %d %d", &e[i].y1, &e[i].y2, &e[i].x);
    e[i].y1 <<= 1, e[i].y2 <<= 1;
    m[i].clear();
    }
    sort(e+1, e+1+M);
    for (int i = 1; i <= M; ++i)
    {
    // printf("%d %d %d\n", e[i].y1, e[i].y2, e[i].x);
    modify(1, e[i].y1, e[i].y2, i, m);
    /* for (it = m[i].begin(); it != m[i].end(); ++it)
    printf(".. %d ", it->first);
    */
    }
    for(int i = 1; i <= M; ++i) // 扫描整个表
    {
    for(it1 = m[i].begin(); it1 != m[i].end(); ++it1) // 遍历第i条线的可见线段
    {
    int k = it1->first; // 记录与其中的第k条线段可见
    for(it2 = m[i].begin(); it2 != m[i].end(); ++it2) // 如果第k条线段与第i条线段有共同的可见线段的话 ans++
    {
    if (m[k].count(it2->first))
    ans++;
    }
    }
    }
    printf("%d\n",ans);
    }
    return 0;
    }





  • 相关阅读:
    top、ps -ef、ps aux的区别及内容详解
    img2pdf 报 img2pdf.AlphaChannelError: Refusing to work on images with alpha channel 的解决方案
    Scrapy命令行调用传入自定义参数
    查询Linux CPU架构
    LeetCode 216. 组合总和 III | Python
    LeetCode 40. 组合总和 II | Python
    LeetCode 39. 组合总和 | Python
    LeetCode 77. 组合 | Python
    LeetCode 347. 前 K 个高频元素 | Python
    LeetCode 107. 二叉树的层次遍历 II | Python
  • 原文地址:https://www.cnblogs.com/Lyush/p/2385436.html
Copyright © 2011-2022 走看看