线段树 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; }