POJ 2528 Mayor's poster

参考了kuangbin的博客 地址戳这儿

主要是参考了这个博客 地址戳这儿

题目大意:n(n<=10000) 个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000) 。求出最后还能看见多少张海报。

对于输入要离散化,之后线段树维护张贴的状态。

留意由于一般的离散化可能导致一些区间被“挤压掉”

比如

1-10 1-4 5-10
1-10 1-4 6-10  被处理成了一样的情况导致错漏。

方法是在相差超过1的相邻点插多一个点,使得离散化的时候不会挤压在一起。还有要注意的地方就是空间开多大,一般是要开4倍点空间,但是由于上述增加点的操作会新增加一些点,直接4*2e4是不行的,直接开8×2e4就ok了。

还有,离散化映射的时候能不用STL最好,宁可开个1kw的数组映射,或者用二分法映射,否则容易TLE。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;

#define ll long long
#define mst(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(ll i=(a);i<(b);++i)
#define rrep(i,a,b) for(ll i=(b-1);i>=a;--i)
#define lb lower_bound
const double eps = 1e-8, PI = acos(-1.0f);
const int inf = 0x3f3f3f3f, maxN = 1e4 + 100;
int N, M, T;

struct Poster { int l, r; } pos[maxN];
int x[maxN * 4];
bool cvis[maxN];
int ans;

// Segment tree
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define lch rt << 1
#define rch rt << 1 | 1
int seg[maxN * 16];
void push_down(int rt) {
    if (seg[rt] == -1)
        return;
    seg[lch] = seg[rch] = seg[rt];
    seg[rt] = -1;
}

void update(int L, int R, int c, int l, int r, int rt) {
    if (L <= l && r <= R) {
        seg[rt] = c;
        return;
    }
    push_down(rt);
    int m = (l + r) >> 1;
    if (L <= m) update(L, R, c, lson);
    if (R > m) update(L, R, c, rson);
}

void query(int l, int r, int rt) {
    if (seg[rt] != -1) {
        if (cvis[seg[rt]] == 0)
            ++ans;
        cvis[seg[rt]] = 1;
        return;
    }
    if (l == r)
        return;
    int m = (l + r) >> 1;
    query(lson);
    query(rson);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
#endif

    scanf("%d", &T);
    while (T--) {
        scanf("%d", &N);
        int cnt = 0;
        rep(i, 0, N) {
            scanf("%d%d", &pos[i].l, &pos[i].r);
            x[cnt++] = pos[i].l;
            x[cnt++] = pos[i].r;
        }
        sort(x, x + cnt);
        int m = unique(x, x + cnt) - x;
        int ocnt = m;
        rep(i, 0, ocnt - 1) {
            if (x[i + 1] - x[i] > 1)
                x[m++] = x[i] + 1;
        }
        sort(x, x + m);

        mst(cvis, 0);
        mst(seg, -1);
        ans = 0;
        rep(i, 0, N) {
            int l = lb(x, x + m, pos[i].l) - x;
            int r = lb(x, x + m, pos[i].r) - x;
            update(l, r, i, 0, m, 1);
        }
        query(0, m, 1);
        printf("%d\n", ans);
    }
    return 0;
}
扫描二维码关注公众号,回复: 968833 查看本文章

猜你喜欢

转载自www.cnblogs.com/Rosebud/p/9067918.html