题目链接:http://poj.org/problem?id=2528
思路分析:线段树处理区间覆盖问题,也可以看做每次给一段区间染不同的颜色,最后求在整段区间上含有的所有颜色种类数;
注意由于区间太大,所以需要离散化;
区间更新:对于线段树的每个结点,标记颜色,初始时没有颜色,标记为0;当更新时,使用延迟标记,需要标记传递到子节点;
区间查询:使用深度优先查询线段树,当某个子节点的颜色不为0时,即停止深度优先搜索,并在map中查询是否已经记录该段区间的颜色;
代码如下:
#include <iostream> #include <algorithm> using namespace std; typedef struct { int x, y; }Pos; const int MAX_N = 10000 + 100; const int MAX_M = 10000000 + 100; int hash_val[MAX_M]; int set[20 * MAX_N], arr[8 * MAX_N]; int map[10 * MAX_N]; Pos position[8 * MAX_N]; int ans; void PushDown(int o) { int lc = 2 * o, rc = 2 * o + 1; if (set[o] != 0) { set[lc] = set[rc] = set[o]; set[o] = 0; } } void Updata(int o, int l, int r, int color, int ql, int qr) { if (ql <= l && r <= qr) set[o] = color; else { int mid = (l + r) / 2; PushDown(o); if (ql <= mid) Updata(2 * o, l, mid, color, ql, qr); if (mid < qr) Updata(2 * o + 1, mid + 1, r, color, ql, qr); } } void Query(int o, int l, int r) { if (set[o] != 0) { if (map[set[o]] == 0) { map[set[o]] = 1; ans++; } } else if (l < r) { int mid = (l + r) / 2; Query(2 * o, l, mid); Query(2 * o + 1, mid + 1, r); } } int main() { int case_times, num; int min_len, max_len; scanf("%d", &case_times); while (case_times--) { memset(set, 0, sizeof(set)); memset(map, 0, sizeof(map)); memset(hash_val, 0, sizeof(hash_val)); scanf("%d", &num); for (int i = 0; i < num; ++i) { scanf("%d %d", &arr[2 * i], &arr[2 * i + 1]); position[i].x = arr[2 * i]; position[i].y = arr[2 * i + 1]; } sort(arr, &arr[2 * num]); for (int i = 0; i < 2 * num; ++i) { if (i == 0) hash_val[arr[i]] = 1; else if (arr[i] == arr[i - 1]) hash_val[arr[i]] = hash_val[arr[i - 1]]; else if (arr[i] == arr[i - 1] + 1) hash_val[arr[i]] = hash_val[arr[i - 1]] + 1; else hash_val[arr[i]] = hash_val[arr[i - 1]] + 2; } min_len = 1; max_len = hash_val[arr[2 * num - 1]]; for (int i = 0; i < num; ++i) { int ql = hash_val[position[i].x]; int qr = hash_val[position[i].y]; Updata(1, min_len, max_len, i + 1, ql, qr); } ans = 0; Query(1, min_len, max_len); printf("%d\n", ans); } return 0; }
poj 2528 Mayor's posters(线段树)
时间: 2024-10-22 12:05:46