POJ 2528 – Mayor's posters

来源:互联网 发布:练歌的软件 编辑:程序博客网 时间:2024/06/08 15:39

Advanced Data Structures :: Segment Tree


Description

在一个很长的墙上贴海报,每张海报的高度和墙一样高。

因此,墙和海报应该被看成线段。

输入即不停得往墙上贴海报。

输出最后墙上可以看到多少张海报(露出一部分也算)。


Type

Advanced Data Structures :: Segment Tree


Analysis

把墙和海报看成线段,让人容易想到线段树。

而贴海报的过程,正好是成段更新的过程。


但是,墙的长度最高可达10000000,这么大的区间无法用线段树。

不过我们发现,海报最多只有10000张,每个海报有左右坐标,那么顶多有20000个点。

可以离散化后,用线段树。(离散化具体内容见参考资料)


利用线段树模拟贴海报的过程,之后,为了统计有几张海报。

我们可以用哈希表,不过统计之前,记得将线段树的延迟标记全部更新到叶子。


不过这题存在一个bug。

从题目的这张图上,我们可以看出。

墙(被当作线段)上的“点”,并不是我们平常所想的没有长度的点。

它应该是一个个单位长度(题目所说的byte)。

因此,看两组数据。

有两张海报[1, 4] [5, 6],他们就会覆盖[1, 6]这张海报。

另外两张海报[1, 3] [5, 6],他们不会覆盖[1, 6]这张海报。

所以,如果我们常规离散化,两组数据的前两张海报都会变成[1, 2] [3, 4] [1, 4],导致相同结果。


因此,在离散化时,注意处理这种某海报右坐标+1正好等于另一张海报左坐标的情况。

一种简单的办法是,如果海报是不相连的,那就在中间多加入一个数字,把两个坐标分隔开。


不过这样做,在POJ反而会WA。

可见POJ上的标程可能没有想到这一点,我们也只能委屈求全了。


Solution

// POJ 2528// Mayor's posters// by A Code Rabbit#include <algorithm>#include <cstdio>#include <cstring>using namespace std;#define LSon(x) ((x) << 1)#define RSon(x) ((x) << 1 | 1)const int MAXN = 10002;const int ROOT = 1;struct Seg {    int w;    int flag;};struct SegTree {    Seg node[MAXN * 4 << 2];    void Build() { memset(node, 0, sizeof(node)); }    void Push(int pos) {        Seg& father = node[pos];        Seg& lson = node[LSon(pos)];        Seg& rson = node[RSon(pos)];        if (father.flag) {            lson.flag = rson.flag = father.flag;            lson.w = rson.w = father.flag;            father.flag = 0;        }    }    void Modify(int l, int r, int pos, int x, int y, int z) {        if (x <= l && r <= y) {            node[pos].w = z;            node[pos].flag = z;            return;        }        Push(pos);        int m = l + r >> 1;        if (x <= m) Modify(l, m, LSon(pos), x, y, z);        if (y > m) Modify(m + 1, r, RSon(pos), x, y, z);    }    void Query(int l, int r, int pos, bool* bo) {        if (l == r) {            bo[node[pos].w] = true;            return;        }        Push(pos);        int m = l + r >> 1;        Query(l, m, LSon(pos), bo);        Query(m + 1, r, RSon(pos), bo);    }};struct Poster {    int l, r;};int n;Poster poster[MAXN];int* pointer[MAXN << 2];bool bo[MAXN];SegTree tree;bool CMP(int* x, int* y) {    return *x < *y;}int main() {    int tot_case;    scanf("%d", &tot_case);    while (tot_case--) {        // Input.        scanf("%d", &n);        for (int i = 0; i < n; i++) {            scanf("%d%d", &poster[i].l, &poster[i].r);            pointer[i * 2] = &poster[i].l;            pointer[i * 2 + 1] = &poster[i].r;        }        // Discretization.        sort(pointer, pointer + 2 * n, CMP);        int num_bytes = 1;        for (int i = 0; i < 2 * n - 1; i++) {            int tmp = num_bytes;            if (*pointer[i] != *pointer[i + 1]) {                if (*pointer[i] + 1 == *pointer[i + 1])                    num_bytes += 1;                else                    num_bytes += 1;                    /* the correct answer should be: "num_bytes += 2;". */            }            *pointer[i] = tmp;        }        *pointer[2 * n - 1] = num_bytes;        // Stick posters by the segments tree.        tree.Build();        int num_posters = 1;        for (int i = 0; i < n; i++)            tree.Modify(1, num_bytes, ROOT, poster[i].l, poster[i].r, num_posters++);        // Compute and output.        memset(bo, false, sizeof(bo));        tree.Query(1, num_bytes, ROOT, bo);        int sum = 0;        for (int i = 0; i < num_posters; i++)            if (bo[i])                sum++;        printf("%d\n", sum);    }    return 0;}



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝拉白色稀便怎么办 5个月宝宝流鼻涕怎么办 5个月婴儿流鼻涕怎么办 五个月宝宝流鼻涕鼻塞怎么办 4个月宝宝流鼻涕怎么办 大便经常是稀的怎么办 拉黑色的稀大便怎么办 孕晚期半夜饿了怎么办 肠胃不好大便不成型怎么办 螃蟹吃多了过敏怎么办 吃螃蟹过敏很痒怎么办 吃螃蟹喝啤酒了怎么办 1个月宝宝拉肚子怎么办 被雨林蝎子蛰了怎么办 在家被蜈蚣咬了怎么办 宝宝被蝎子蜇了怎么办 仓鼠只吃面包虫怎么办 套装但是装等低怎么办 被香港人骗了钱怎么办 被红头蛇咬了怎么办 爸妈吵架闹离婚怎么办 包包用酒精擦了怎么办 灰色泰迪毛发白怎么办 手被野猫抓伤了怎么办 想去香港玩两天怎么办 受凉了一直想吐怎么办 受寒后头晕想吐怎么办 肚子受凉了想吐怎么办 想吐但吐不出来怎么办 抽烟抽的牙黄怎么办 借了大耳窿的钱怎么办 5岁左眼视力不好怎么办 老公才30性不行怎么办 老婆出轨跑了怎么办啊 海螺吃多了头晕怎么办 读书的好与不好怎么办 衣服泡久了发黄怎么办 白衣服洗变色了怎么办 高达贴纸贴错了怎么办 小孩大门牙长歪怎么办 小孩乳牙长歪了怎么办