First, the content
Second, the idea
-
Is seeking a total of how many posters they can see, attach a color to each poster, and finally find yourself able to see how many colors.
-
Discrete data, because it is continuous for a period of, so that when the difference between the two points is greater than 1, it should add a point in the middle.
Such as [1, 1,4] [10] [5, 10] is discretization [1,4] [1,2] [3, 4]
However, [1, 10] [6] [1, 4, 10 discretization] [1,4] is [1,2] [3, 4], however, the number should be seen in this case 3
so we should add a point intermediate 5 in 4 and 6, carried out by a modified section when you can not go wrong. -
Color [] The initial value of -1 indicates no color or a variety of colors, with each time we are updated to the new time period on the line section, and each time pushdown (); the interval period interval divided into two stages, due to the coverage interval may be a period of sub-intervals.
- The last query () how many colors there are a query on the list, with a vis record color've seen .
Third, the code
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 2e4 + 5;
//color用来保存一段区间的颜色,vis用来统计颜色 lId保存海报的左端点 id保存离散化后的编号
int color[maxn << 4], vis[maxn << 4], lId[maxn], rId[maxn], id[maxn << 2];
int t, n, cnt, ans;
void pushdown(int id) {
if (color[id] == -1) return;
//对修改过的区间进行下放
color[id << 1] = color[id << 1 | 1] = color[id];
color[id] = -1;
}
void update(int id, int l, int r, int x, int y, int v) {
if (x <= l && r <= y) {
//对区间进行修改
color[id] = v;
return;
}
pushdown(id);
int mid = (l + r) >> 1;
if (x <= mid) {
update(id << 1, l , mid, x, y, v);
}
if (y > mid) {
update(id << 1 | 1, mid + 1, r, x, y, v);
}
//这种还不用pushup
}
void query(int id, int l, int r) {
if (color[id] != -1) {
//记录一种color
if (!vis[color[id]]) {
ans++;
vis[color[id]] = 1;
}
return;
}
if (l == r) return;
int mid = (l + r) >> 1;
query(id << 1, l, mid);
query(id << 1 | 1, mid + 1,r);
}
int main() {
scanf("%d", &t);
while (t--) {
cnt = 0;
ans = 0;
memset(color, -1, sizeof(color));
memset(vis, 0, sizeof(vis));
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d%d", lId + i, rId + i);
id[++cnt] = lId[i];
id[++cnt] = rId[i];
}
sort(id + 1, id + cnt + 1);
int t = unique(id + 1, id + cnt + 1) - id - 1;
int m = t;
for (int i = 2; i <= t; i++) {
if (id[i] - id[i - 1] > 1) {
//成段的离散化若差值大于1 中间还应该添加一个点
id[++m] = id[i - 1] + 1;
}
}
cnt = m;
sort(id + 1, id + cnt + 1);
for (int i = 1; i <= n; i++) {
int x = lower_bound(id + 1, id + cnt + 1, lId[i]) - id;
int y = lower_bound(id + 1, id + cnt + 1, rId[i]) - id;
update(1, 1, cnt, x, y, i);
}
query(1, 1, cnt);
printf("%d\n", ans);
}
return 0;
}