http://poj.org/problem?id=2528
#include <cstdio> #include <iostream> #include <set> #include <cstring> #include <string> #define left rt<<1 #define right rt<<1|1 using namespace std; const int MAXN = 32768 + 5; int setv[MAXN << 2]; // 很不科学,这里一定要开大一点才AC,按道理说2*MAXN-1的空间就够了的。。。WA到哭泣 int hash[10000005]; struct Interval{ int l, r; } a[10005]; bool color[10005]; int ans; void pushdown(int rt) { if(setv[rt] != -1) { setv[left] = setv[right] = setv[rt]; setv[rt] = -1; } } void update(int ql, int qr, int x, int rt, int l, int r) { if(ql <= l && r <= qr) { setv[rt] = x; return; } pushdown(rt); int m = (l + r) >> 1; if(ql <= m) update(ql, qr, x, left, l, m); if(qr > m) update(ql, qr, x, right, m+1, r); } void query(int ql, int qr, int rt, int l, int r) { if(setv[rt] != -1) { if(!color[setv[rt]]) { ans++; color[setv[rt]] = 1; } return; } if(l==r) return; pushdown(rt); int m = (l + r) >> 1; if(ql <= m) query(ql, qr, left, l, m); if(qr > m) query(ql, qr, right, m+1, r); } int main () { int c, n; scanf("%d", &c); while(c--) { scanf("%d", &n); set<int> st; for(int i=0; i<n; i++) { scanf("%d%d", &a[i].l, &a[i].r); st.insert(a[i].l); st.insert(a[i].r); } int pre, tot=0; for(set<int>::iterator p=st.begin(); p != st.end(); ++p) { if(p==st.begin()) { hash[*p] = ++tot; } else { if(*p - pre == 1) { hash[*p] = ++tot; } else { hash[*p - 1] = ++tot; hash[*p] = ++tot; } } pre = *p; } memset(setv, -1, sizeof(setv)); memset(color, false, sizeof(color)); for(int i=0; i<n; i++) { update(hash[a[i].l], hash[a[i].r], i+1, 1, 1, tot); } ans = 0; query(1, tot, 1, 1, tot); printf("%d\n", ans); } return 0; }
一种更节省空间的版本,省去了hash数组,因为已经排序了,所以可以二分查找找到对应的下标:
#include <cstdio> #include <iostream> #include <set> #include <cstring> #include <string> #include <algorithm> #define left rt<<1 #define right rt<<1|1 using namespace std; const int MAXN = 32768 + 5; int setv[MAXN << 2]; struct Interval{ int l, r; } a[10005]; bool color[10005]; int ans; int t[10005 * 3]; void pushdown(int rt) { if(setv[rt] != -1) { setv[left] = setv[right] = setv[rt]; setv[rt] = -1; } } void update(int ql, int qr, int x, int rt, int l, int r) { if(ql <= l && r <= qr) { setv[rt] = x; return; } pushdown(rt); int m = (l + r) >> 1; if(ql <= m) update(ql, qr, x, left, l, m); if(qr > m) update(ql, qr, x, right, m+1, r); } void query(int ql, int qr, int rt, int l, int r) { if(setv[rt] != -1) { if(!color[setv[rt]]) { ans++; color[setv[rt]] = 1; } return; } if(l==r) return; pushdown(rt); int m = (l + r) >> 1; if(ql <= m) query(ql, qr, left, l, m); if(qr > m) query(ql, qr, right, m+1, r); } int Bin(int key,int n,int X[]) { int l = 1,r = n; while (l <= r) { // [l, r] int m = (l+r) >> 1; if(X[m] == key) return m; if(X[m] < key) l=m+1; else r=m-1; } return -1; } int main () { int c, n; scanf("%d", &c); while(c--) { scanf("%d", &n); set<int> st; for(int i=0; i<n; i++) { scanf("%d%d", &a[i].l, &a[i].r); st.insert(a[i].l); st.insert(a[i].r); } memset(setv, -1, sizeof(setv)); memset(color, false, sizeof(color)); int tot = 0; for(set<int>::iterator p=st.begin(); p != st.end(); ++p) { t[++tot] = *p; } int temp_tot=tot; for(int i=2; i<=temp_tot; i++) { if(t[i]-t[i-1] > 1) t[++tot] = t[i]-1; } sort(t+1, t+tot+1); for (int i = 0; i < n; i++) { int l = Bin(a[i].l , tot , t); int r = Bin(a[i].r , tot , t); update(l, r, i, 1, 1, tot); } ans = 0; query(1, tot, 1, 1, tot); printf("%d\n", ans); } return 0; }
POJ - 2528 - Mayor's posters 【线段树+离散化+补点】
时间: 2024-10-09 22:07:49