题意:m次询问给你区间段的颜色,然后区间修改颜色覆盖,统计最后各种颜色出现的段数
思路:就是线段树比较基本的操作,区间修改,再把区间所有的值赋值给统计数组,然后统计段个数
完整代码:
#include <cstdio> #include <cstring> const int maxn = 8000 ; const int N = 8010 << 2; int n; int color[N], segment[N], ans[N]; void PushDown(int u) { if (color[u] != -1) { color[u << 1] = color[u << 1 | 1] = color[u]; color[u] = -1; } } void modify(int u, int l, int r, int L, int R, int c) { if (L <= l && r <= R) { color[u] = c; return ; } if (color[u] == c) return ; PushDown(u); int mid = (l + r) >> 1; if (L <= mid) modify(u << 1, l, mid, L, R, c); if (R > mid) modify(u << 1 | 1, mid + 1, r, L, R, c); } void query(int u, int l, int r) { //这一次query即是把从1到n的color复制到segment里面 if (color[u] != -1) { for (int i = l; i <= r; i++) segment[i] = color[u]; return ; } if (l == r) return ; int mid = (l + r) >> 1; query(u << 1, l, mid); query(u << 1 | 1, mid + 1, r); } int main() { while (~scanf("%d", &n)){ memset(color, -1, sizeof(color)); memset(segment, -1, sizeof(segment)); memset(ans, 0, sizeof(ans)); int a, b, c; while (n--) { scanf("%d%d%d", &a, &b, &c); if (a >= b) continue; modify(1, 1, maxn, a + 1, b, c); } query(1, 1, maxn); int i = 1; while (i <= maxn) { int c = segment[i], j = i + 1; if (c == -1) { i++; continue; } while (segment[j] == c && j <= maxn) j++; ans[c]++; i = j; } for (int i = 0; i <= maxn; i++) if (ans[i]) printf("%d %d ", i, ans[i]); printf(" "); } return 0; }