线段树 G - Mayor's posters 小技巧

G - Mayor's posters POJ - 2528 

这个题目要倒着来写,从后面往前面贴,因为前面的有些会被后面的覆盖。

所以我们就判断这张海报的位置有没有完全被覆盖,如果完全被覆盖了就不能贴,但是没有完全被覆盖就可以贴上去,然后更新掉这一段。

 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e5 + 100;
pair<int, int>pii[maxn];
int a[maxn];
struct node {
    int l, r, lazy;
}tree[maxn * 4];

void push_up(int id) {
    if (tree[id << 1].lazy&&tree[id << 1 | 1].lazy) tree[id].lazy = 1;
}

void push_down(int id) {
    if (tree[id].lazy) {
        tree[id << 1].lazy = 1;
        tree[id << 1 | 1].lazy = 1;
    }
}

void build(int id, int l, int r) {
    tree[id].l = l;
    tree[id].r = r;
    tree[id].lazy = 0;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(id << 1, l, mid);
    build(id << 1 | 1, mid + 1, r);
}

int query(int id, int l, int r) {
    //printf("id=%d \n", id);
    if (l <= tree[id].l&&r >= tree[id].r) {
        if (tree[id].lazy) return 0;
        return 1;
    }
    push_down(id);
    int ans = 0;
    int mid = (tree[id].l + tree[id].r) >> 1;
    if (l <= mid) ans = max(ans, query(id << 1, l, r));
    if (r > mid) ans = max(ans, query(id << 1 | 1, l, r));
    return ans;
}

void update(int id, int l, int r) {
    if (l <= tree[id].l&&r >= tree[id].r) {
        tree[id].lazy = 1;
        return;
    }
    push_down(id);
    int mid = (tree[id].l + tree[id].r) >> 1;
    if (l <= mid) update(id << 1, l, r);
    if (r > mid) update(id << 1 | 1, l, r);
    push_up(id);
}


int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        int n, cnt = 0;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            int x, y;
            scanf("%d%d", &x, &y);
            pii[i] = make_pair(x, y);
            a[++cnt] = x;
            a[++cnt] = x - 1;
            a[++cnt] = x + 1;
            a[++cnt] = y - 1;
            a[++cnt] = y;
            a[++cnt] = y + 1;
        }
        sort(a + 1, a + 1 + cnt);
        int size = unique(a + 1, a + 1 + cnt) - (a + 1);
        build(1, 1, size);
        // for(int i=1;i<=size;i++)
        // {
        //     printf("i=%d %d\n", i, a[i]);
        // }
        int ans = 0;
        for (int i = n; i >= 1; i--) {
            int l = pii[i].first, r = pii[i].second;
            int t1 = lower_bound(a + 1, a + 1 + size, l) - a;
            int t2 = lower_bound(a + 1, a + 1 + size, r) - a;
            //printf("%d %d\n", t1, t2);
            if (query(1, t1, t2)) {
                ans++;
                update(1, t1, t2);
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
View Code

 



posted @ 2019-05-09 20:37  EchoZQN  阅读(192)  评论(0编辑  收藏  举报