Description
Input
Output
Sample Input
1 5 1 4 2 6 8 10 3 4 7 10
Sample Output
4
在一面墙上贴海报,求最终能看到的海报数量。
先把所有数离散化,映射为新的数,在用线段树模板就行了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int col[1 << 17]; int ans; typedef struct S { int pos, id; } NODE; NODE node[20010]; bool cmp(NODE a, NODE b) { return a.pos < b.pos; } int ls[20010]; int vis[40010]; void pushdown(int rt, int len) { if (col[rt] != -1) { col[rt << 1] = col[rt << 1 | 1] = col[rt]; col[rt] = -1; } } void update(int L, int R, int c, int l, int r, int rt) { if (L <= l && R >= r) { col[rt] = c; return; } pushdown(rt, r - l + 1); 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 (col[rt] != -1) { if (!vis[col[rt]]) { vis[col[rt]] = 1; ++ans; } return; } if (l == r) return; int m = (l + r) >> 1; query(lson); query(rson); } int main() { int T, i, j, n, max; scanf("%d", &T); while (T--) { scanf("%d", &n); memset(col, -1, sizeof (col)); memset(vis,0,sizeof(vis)); for (i = 0; i < n; ++i) { node[i << 1].id = i << 1; scanf("%d", &node[i << 1].pos); node[i << 1 | 1].id = i << 1 | 1; scanf("%d", &node[i << 1 | 1].pos); } sort(node, node + n + n, cmp); ls[node[0].id] = 0; for (i = 1; i < n + n; ++i) { if (node[i].pos == node[i - 1].pos) { ls[node[i].id] = ls[node[i - 1].id]; } else if (node[i].pos == node[i - 1].pos + 1) { ls[node[i].id] = ls[node[i - 1].id] + 1; } else { ls[node[i].id] = ls[node[i - 1].id] + 2; } } max = ls[node[n + n - 1].id]; for (i = 0; i < n; ++i) { update(ls[i << 1], ls[i << 1 | 1], i, 0, max, 1); } ans = 0; query(0, max, 1); printf("%d\n", ans); } return 0; }