Description
Input
Output
Sample Input
1 5 1 4 2 6 8 10 3 4 7 10
Sample Output
4
解题思路:
难点在于离散化,数据过大,必须进行离散化,而且不能是普通的离散化。如果两个相邻海报没有紧挨着,则在离散化的时候必须给两个海报之间留有间隔。
打个比方:(1,10)(1,4)(5,10)这组数据,普通离散化后应该为(1,4)(1,2)(3,4),那么答案应该为2。
(1,10)(1,3)(6,10)这组数据普通离散化后应该也为(1,4)(1,2)(3,4),答案也为2,可显然这题答案应该为3。问题就出在未留有间隔。
解决方案就是判断是否紧挨,若没有紧挨,就在离散化的时候往数组里面加一个数。在这里我采用的是用结构体来进行离散化。
剩下的就是求海报出现的个数问题,对线段进行着色,后贴的海报着色会覆盖之前的海报,最后统计颜色的种数即可。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 const int maxn = 11111; int x[maxn << 2], col[maxn << 4], ans, c[maxn << 2]; bool flag[maxn << 2]; struct san { int a, pos; }f[maxn << 2]; bool cmp(san v, san t) { return v.a < t.a; } void PushDown(int rt) { if(col[rt] != 0) { col[rt << 1] = col[rt << 1 | 1] = col[rt]; col[rt] = 0; } } 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); int m = (l + r) >> 1; if (L <= m) update(L , R , c , lson); if (m < R) update(L , R , c , rson); } void query(int l, int r, int rt) { if(col[rt] != 0) { if(!flag[col[rt]]) // 用flag检测该颜色是否之前出现过 { ans++; flag[col[rt]] = true; } return; } if(l == r) return; int m = (l + r) >> 1; query(lson); query(rson); } int main() { int t, n, ll, rr; scanf("%d", &t); while(t--) { ans = 0; memset(col , 0, sizeof(col)); memset(flag, false, sizeof(flag)); scanf("%d", &n); int k = 0; for(int i = 1; i <= n; i++) { scanf("%d%d", &ll, &rr); // 用f存储左右范围的值,因此有2*n个 f[++k].a = ll; f[k].pos = k; f[++k].a = rr; f[k].pos = k; } sort(f + 1, f + k + 1, cmp); //进行第一次排序 int t = 2 * n; for(int i = 2; i <= 2 * n; i++) { if(f[i].a > f[i - 1].a + 1) //判断是否紧挨,无需考虑两者是否属于同一个海报 { f[++t].a = f[i - 1].a + 1; // 未紧挨就加上一个紧挨的数 f[t].pos = 0; // 使其pos为0,就不会在离散化时进入有效值中 } } int m = 1; c[1] = 1; sort(f + 1, f + t + 1, cmp); // 二次排序,产生间隔 for(int i = 2; i <= t; i++) // 去重处理 { if(f[i].a == f[i - 1]. a) c[i] = m; else c[i] = ++m; } for(int i = 1; i <= t; i++) // 得到有效值 x[f[i].pos] = c[i]; for(int i = 1; i <= 2 * n - 1; i += 2) //进行着色 update(x[i], x[i + 1], i, 1, 4 * n, 1); query(1, 4 * n, 1); // 求颜色种类 printf("%d\n", ans); } return 0; }
Mayor's posters(线段树 + 离散化),布布扣,bubuko.com
原文:http://blog.csdn.net/userluoxuan/article/details/38559659