线段树+离散化处理。
写的我好蛋疼啊!!!
不过总算过了。
/* POJ: 2528 Mayor's posters */ #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <functional> using namespace std; const int MaxN = 10005; const int TreeSize = 100005; struct SegmentTree { int left, right; int poster; } tree[TreeSize]; struct Descrete { int point, num; bool operator < (const struct Descrete &t) const { return point < t.point; } } des[2 * MaxN]; bool visible[MaxN]; int n; int seg[2 * MaxN][2]; int ans; void init(int i, int a, int b) { tree[i].left = a; tree[i].right = b; tree[i].poster = -1; if(a < b) { int mid = (a + b) >> 1; init(2 * i, a, mid); init(2 * i + 1, mid + 1, b); } } void insert(int i, int a, int b, int p) { if(tree[i].left >= a && tree[i].right <= b) { tree[i].poster = p; return ; } if(tree[i].poster > 0) { tree[2 * i].poster = tree[i].poster; tree[2 * i + 1].poster = tree[i].poster; tree[i].poster = -1; } int mid = (tree[i].left + tree[i].right) >> 1; if(b <= mid) insert(2 * i, a, b, p); else if(a > mid) insert(2 * i + 1, a, b, p); else { insert(2 * i, a, mid, p); insert(2 * i + 1, mid + 1, b, p); } } void find(int i) { if(tree[i].poster > 0) { if(!visible[tree[i].poster]) { ans++; visible[tree[i].poster] = true; } return ; } find(2 * i); find(2 * i + 1); } int main() { //freopen("data.in", "rb", stdin); int c; scanf("%d", &c); while(c--) { scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%d%d", &des[i * 2].point, &des[i * 2 + 1].point); des[i * 2].num = -(i + 1); des[i * 2 + 1].num = i + 1; } sort(des, des + 2 * n); int total = 1; int tmp = des[0].point; for(int i = 0; i < 2 * n; i++) { if(des[i].point != tmp) { total++; tmp = des[i].point; } if(des[i].num < 0) seg[-des[i].num][0] = total; else seg[des[i].num][1] = total; } init(1, 1, total); for(int i = 1; i <= n; i++) insert(1, seg[i][0], seg[i][1], i + 1); memset(visible, false, sizeof(visible)); ans = 0; find(1); printf("%d\n", ans); } return 0; }