线段树,离散化;
WA了三次,前两次主要是查询时只要遇到标记了颜色就要返回,而不是标记颜色并且没记录过就返回,后一次是空间开的小,因为离散化可能使数据量增加一倍,因此空间至少要开到区间数目的 4 倍;
-----------------------------------------------------------
2012/4/15
# include <cstdio> # include <cstring> # include <algorithm> using namespace std; # define N 10000 + 5 int n, m, li[N], ri[N]; int h[N], p[4 * N], c[4 * 4 * N]; void build(int r, int x, int y) { c[r] = 0; if (x == y) return ; int mid = (x+y) >> 1, ls = r << 1, rs = r << 1 | 1; build(ls, x, mid); build(rs, mid+1, y); } void pushdown(int r) { if (c[r]) c[r << 1] = c[r << 1 | 1] = c[r], c[r] = 0; } void color(int r, int x, int y, int s, int t, int val) { if (s<=x && y<=t) { c[r] = val; return ;} pushdown(r); int mid = (x+y) >> 1, ls = r << 1, rs = r << 1 | 1; if (s <= mid) color(ls, x, mid, s, t, val); if (mid+1 <= t) color(rs, mid+1, y, s, t, val); // update(r); // no-need } // query(int r, int x, int y, int s, int t, int &ans) void query(int r, int x, int y, int &ans) { if (c[r] != 0) { if (h[c[r]] == 0) {h[c[r]] = 1; ++ans;} return ; } if (x == y) return; int mid = (x+y) >> 1, ls = r << 1, rs = r << 1 | 1; query(ls, x, mid, ans); query(rs, mid+1, y, ans); } int Bsearch(int x, int *v, int n) { int low, high, mid; low = 0; high = n - 1; while (low <= high) { mid = (low + high) >> 1; if (x < v[mid]) high = mid - 1; else if (x > v[mid]) low = mid + 1; else return mid; } return -1; } void init(void) { int k; m = 0; scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%d%d", &li[i], &ri[i]); p[m++] = li[i], p[m++] = ri[i]; } sort(p, p+m); k = m, m = 1; for (int i = 1; i < k; ++i) if (p[i] != p[i-1]) p[m++] = p[i]; for (int i = m-1; i > 0; --i) if (p[i] != p[i-1]+1) p[m++] = p[i-1] + 1; sort(p, p+m); build(1, 1, m); } void solve(void) { int s, t, ans; for (int i = 0; i < n; ++i) { s = Bsearch(li[i], p, m) + 1; t = Bsearch(ri[i], p, m) + 1; color(1, 1, m, s, t, i+1); } memset(h, 0, sizeof(h[0])*n+5); ans = 0; query(1, 1, m, ans); printf("%d\n", ans); } int main() { int T; scanf("%d", &T); while (T--) { init(); solve(); } return 0; }
-----------------------------------------------------------
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 <algorithm> # include <cstdlib> # define C 12000 # define N 4 * C using namespace std; int n, li[C], ri[C]; int m, h[C], mir[N], c[4 * N]; int cmp(const void *x, const void *y) { return (*(int*)x - *(int*)y); } void pushdown(int r) { if (c[r]) { c[r << 1] = c[r << 1 | 1] = c[r]; c[r] = 0; } } void color(int r, int x, int y, int s, int t, int val) { if (s<=x && y<=t) { c[r] = val; return ; } pushdown(r); int mid = (x+y) >> 1, ls = r << 1, rs = r << 1 | 1; if (s <= mid) color(ls, x, mid, s, t, val); if (mid+1 <= t) color(rs, mid+1, y, s, t, val); } void query(int r, int x, int y, int &ans) { if (c[r]) { if (!h[c[r]]) ++ans; h[c[r]] = 1; return ; } if (x == y) return ; pushdown(r); int mid = (x+y) >> 1, ls = r << 1, rs = r << 1 | 1; query(ls, x, mid, ans); query(rs, mid+1, y, ans); } void build(int r, int x, int y) { if (x == y) { c[x] = 0; return ; } int mid = (x+y) >> 1, ls = r << 1, rs = r << 1 | 1; build(ls, x, mid); build(rs, mid+1, y); } void init(void) { int p = 0; scanf("%d", &n); for (int i = 1; i <=n ; ++i) { scanf("%d%d", &li[i], &ri[i]); mir[p++] = li[i], mir[p++] = ri[i]; } sort(mir, mir+p); m = 1; for (int i = 1; i < p; ++i) if (mir[i] != mir[i-1]) mir[m++] = mir[i]; for(int i = m-1; i > 0; --i) if (mir[i] != mir[i-1]+1) mir[m++] = mir[i-1] + 1; sort(mir, mir+m); build(1, 1, m); } void solve(void) { int s, t, ans; for (int i = 1; i <= n; ++i) { s = (int*)bsearch(li+i, mir, m, sizeof(int), cmp) - mir + 1; t = (int*)bsearch(ri+i, mir, m, sizeof(int), cmp) - mir + 1; color(1, 1, m, s, t, i); } memset(h, 0, sizeof(h)); ans = 0; query(1, 1, m, ans); printf("%d\n", ans); } int main() { int T; scanf("%d", &T); while (T--) { init(); solve(); } return 0; }
-----------------------------------------------------------