标签:
题意:给n张海报,按顺序贴海报,问最后能看到多少张不同的海报。
解法:成段更新线段树 + 离散化。这道题因为给出的数字是单位长度,所以普通的离散化是有问题的,借鉴了大神的方法:http://notonlysuccess.me/?p=978
一开始我的离散化方法是把单位长度改为数轴坐标……但是2 2 1 1 3 3这组样例是有问题的……TUT
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long long using namespace std; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 map <int, int> m; int l[20005], r[20005]; int col[11111 << 4]; bool flag[20005]; int ans; void pushDown(int rt) { if(col[rt] != -1) col[rt << 1] = col[rt << 1 | 1] = col[rt]; col[rt] = -1; } void update(int ll, int rr, int c, int l, int r, int rt) { if(ll <= l && rr >= r) { col[rt] = c; return ; } pushDown(rt); int m = (l + r) >> 1; if(ll <= m) update(ll, rr, c, lson); if(rr > m) update(ll, rr, c, rson); } void query(int l, int r, int rt) { if(col[rt] != -1) { if(!flag[col[rt]]) { ans++; } flag[col[rt]] = true; return; } if(l == r) return ; int m = (l + r) >> 1; query(lson); query(rson); } int main() { int T; scanf("%d", &T); while(T--) { m.clear(); memset(col, -1, sizeof col); int n; scanf("%d", &n); int maxn = 1; for(int i = 0; i < n; i++) { scanf("%d%d", &l[i], &r[i]); m[l[i]]++; m[r[i]]++; } map <int, int> :: iterator ite = m.begin(), ite1 = m.begin(); ite -> second = 0; ite++; for(; ite != m.end(); maxn++, ite++, ite1++) { if(ite -> first - ite1 -> first > 1) m[ite -> first + 1] = maxn++; ite -> second = maxn; } for(int i = 0; i < n; i++) { update(m[l[i]], m[r[i]], i, 0, maxn - 1, 1); } ans = 0; memset(flag, 0, sizeof flag); query(0, maxn - 1, 1); printf("%d\n", ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/Apro/p/4503059.html