poj 2528(区间修改+离散化)

题意:有一个黑板上贴海报,给出每个海报在黑板上的覆盖区间为l r,问最后多少个海报是可见的。

题解:因为l r取值到1e7,肯定是要离散化的,但普通的离散化会出问题,比如[1,10],[1,4],[4,6]普通得到答案是2,但其实是3,改进的离散化方法如果两个数字相差大于1,就在中间补一个数字。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 10005;
int n, l[N], r[N], a[N << 3], tree[N << 4], vis[N], res;

void pushdown(int k) {
    if (tree[k] != -1) {
        tree[k * 2] = tree[k * 2 + 1] = tree[k];
        tree[k] = -1;
    }
}

void modify(int k, int left, int right, int l1, int r1, int x) {
     if (l1 <= left && right <= r1) {
         tree[k] = x;
         return;
     }
     pushdown(k);
     int mid = (left + right) / 2;
     if (mid >= l1)
        modify(k * 2, left, mid, l1, r1, x);
    if (mid < r1)
        modify(k * 2 + 1, mid + 1, right, l1, r1, x);
}

void query(int k, int left, int right) {
    if (left == right) {
        if (!vis[tree[k]]) {
            res++;
            vis[tree[k]] = 1;
       }
       return;
    }
    pushdown(k);
    int mid = (left + right) / 2;
    query(k * 2, left, mid);
    query(k * 2 + 1, mid + 1, right);
}

int main() {
    int t;
    scanf ("%d", &t);
    while (t--) {
        memset(tree, -1, sizeof(tree));
        memset(vis, 0, sizeof(vis));
        int cnt = 0;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
             scanf ("%d%d", &l[i], &r[i]);
             a[++cnt] = l[i];
             a[++cnt] = r[i];
        }
        sort(a + 1, a + 1 + cnt);
        cnt = unique(a + 1, a + 1 + cnt) - (a + 1);
        int cnt2 = cnt;
        for (int i = 2; i <= cnt; i++)
            if (a[i] - a[i - 1] > 1)
                a[++cnt2] = a[i] - 1;
        cnt = cnt2;
        sort(a + 1, a + 1 + cnt);
        for (int i = 1; i <= n; i++) {
            int l1 = lower_bound(a + 1, a + 1 + cnt, l[i]) - a;
            int r1 = lower_bound(a + 1, a + 1 + cnt, r[i]) - a;
            modify(1, 1, cnt, l1, r1, i);
        }
    res = 0;
    query(1, 1, cnt);
        printf("%d\n", res);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 04:19:41

poj 2528(区间修改+离散化)的相关文章

poj 2528(区间改动+离散化)

题意:有一个黑板上贴海报.给出每一个海报在黑板上的覆盖区间为l r,问最后多少个海报是可见的. 题解:由于l r取值到1e7,肯定是要离散化的,但普通的离散化会出问题.比方[1,10],[1,4],[6,10]普通得到答案是2,但事实上是3.改进的离散化方法假设两个数字相差大于1,就在中间补一个数字. #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> u

POJ 2528 (线段树+离散化) Mayor&#39;s posters

因为将每个单位都作为一个最小单元的话会爆内存的 所以,将海报的每个端点进行排序,将这些端点最为最小的区间. 毕竟是刚刚接触线段树,理解起来还有些吃力,还是那句话,题做多了慢慢就好了. 萌萌的AC代码君贴上. 1 //#define LOCAL 2 #include <iostream> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 7 int n; 8 struct CPost 9

Mayor&#39;s posters POJ - 2528 (线段树 + 离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 86160   Accepted: 24734 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

POJ - 2528 区间离散化,线段树区间修改,区间询问

这个题非常有意思的地方是,我们发现区间[1,4]和[5,8]是紧挨着的,因为这个的数代表的是一段区间,原本我们对于普通的离散, a[1]=1,a[2]=5,a[3]=6,a[4]=8;数组下标就是重新离散的位置,但是a[2]和a[3]明显不重叠,为此我们需要重新考虑离散的内容,其实不妨这样,如果区间的间隔大于1,那么我们插入一个数a[i]+1,这样就强行把a[i]和a[i+1]分开,因为 如三张海报为:1~10 1~4 6~10 离散化时 X[ 1 ] = 1, X[ 2 ] = 4, X[ 3

POJ 2528 区间染色,求染色数目,离散化

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 47905   Accepted: 13903 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

poj 2528(线段树+离散化) 市长的海报

http://poj.org/problem?id=2528 题目大意是市长竞选要贴海报,给出墙的长度和依次张贴的海报的长度区间(参考题目给的图),问最后你能看见的海报有几张 就是有的先贴的海报可能会被后贴的海报完全盖住,那就看不见了 这里就非常抽象的区间更新,墙的长度为建立线段树的总区间,每贴一张海报代表将这个区间的颜色涂为相应的,每张海报的颜色当然 都不相同,求最后又多少种颜色就行,但这里还要用到基础的离散化 离散化是把无限空间中无限的个体映射到有限的空间中去,以此提高算法的时空效率. 简单

zoj 3299(区间修改+离散化)

题意:有n个由小木块组成的长条木块要掉下来,给出木块的左右区间,然后有给了m个木板的左右区间和高度用来接住木块,因为木块是由小木块接触组成的,也就是木板可以接住一部分的木块,剩下的会继续掉落,问最后每个木板上有多少个小木块. 题解:这道题用线段树可解,还有另一个比较机智的做法. 先说线段树,左右区间到3×1e7,如果用线段树解决需要离散化.把木板从低到高排序后用一个线段树flag维护每个区间对应的木板编号,这样高的木板就可以覆盖低木板的编号,然后用另一个线段树sum维护每个长条木块在每个区间内的

LightOJ 1089 - Points in Segments (II) 线段树区间修改+离散化

http://www.lightoj.com/volume_showproblem.php?problem=1089 题意:给出许多区间,查询某个点所在的区间个数 思路:线段树,由于给出的是区间,查询的是点,考虑将其离线并离散化,普通线段树即可. /** @Date : 2016-12-17-20.49 * @Author : Lweleth ([email protected]) * @Link : https://github.com/ * @Version : */ #include<bi

POJ 2528 线段树+离散化

题意是给你n张海报,告诉你每张海报的宽度和先后顺序,海报会重叠,问你露在外面的海报有多少张?这题主要是离散化理解了好久,关键在于建hash表时不能选择最普通的一一对应,为什么?看了网上一组数据后瞬间就明白了:1,10  1,4  6,10. Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 51347   Accepted: 14875 Description The citizens of