poj/OpenJ_Bailian - 2528 离散化+线段树

传送门:http://bailian.openjudge.cn/practice/2528?lang=en_US

//http://poj.org/problem?id=2528

题意:

给你n长海报,每张海报在墙上贴的区间范围是l,r

问你这n张海报贴完后,可以看见的海报数量是多少

题解:

离散化+线段树

因为l,r的数据范围是1e7,而题目只给了64MB的空间,直接存的话空间会炸掉,所以需用用到离散化的技巧

然后按照端点单点更新即可

现在重新写这题发现这个题坑点在于每一个点他都代表一个长度为1的东东,所以我们普通的离散话会出问题

1-10 1-4 5-10
1-10 1-4 6-10

譬如 如上这组例子

所以我们离散化时做一下优化, 如果相邻间数字间距大于1时我们就在其中加上任意一个数字

这样离散话下来后做线段树就可以过
这组数据
3
5 6
4 5
6 8
3
1 10
1 3
6 10
5
1 4
2 6
8 10
3 4
7 10

这组数据

答案是3,3,4

代码:

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"

const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3;
struct node {
    int l, r;
} q[maxn];
int col[maxn];
int vis[maxn];
int ans;
void push_down(int rt) {
    if(col[rt] != -1) {
        col[ls] = col[rs] = col[rt];
        col[rt] = -1;
    }
    return;
}
void update(int L, int R, int c, int l, int r, int rt) {
    if(L <= l && r <= R) {
        col[rt] = c;
        return;
    }
    push_down(rt);
    int mid = (l + r) >> 1;
    if(L <= mid) update(L, R, c, lson);
    if(R > mid) update(L, R, c, rson);
}
void query(int l, int r, int rt) {
    if(col[rt] != -1) {
        if(!vis[col[rt]]) ans++;
        vis[col[rt]] = true;
        return;
    }
    if(l == r) return;
    int mid = (l + r) >> 1;
    query(lson);
    query(rson);
}
int x[maxn];
int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        int cnt = 0;
        int n;
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            scanf("%d%d", &q[i].l, &q[i].r);
            x[cnt++] = q[i].l;
            x[cnt++] = q[i].r;
        }
        sort(x, x + cnt);
        int m = 1;
        for(int i = 1; i < cnt; i++) {
            if(x[i] != x[i - 1]) {
                x[m++] = x[i];
            }
        }
        for(int i = m - 1; i >= 1; i--) {
            if(x[i] != x[i - 1] + 1) {
                x[m++] = x[i - 1] + 1;
            }
        }
        sort(x, x + m);
        memset(col, -1, sizeof(col));
        for(int i = 0; i < n; i++) {
            int l = lower_bound(x, x + m, q[i].l) - x;
            int r = lower_bound(x, x + m, q[i].r) - x;
            update(l, r, i, 0, m, 1);
        }
        ans = 0;
        memset(vis, false, sizeof(vis));query(0, m, 1);
        printf("%d\n",ans );

    }
}
posted @ 2019-05-14 21:45  buerdepepeqi  阅读(181)  评论(0编辑  收藏  举报