链接:https://vjudge.net/problem/ZOJ-1610#author=0
题意:
给n个区间,是区间,对区间进行染色。
区间的范围是1-8000。
求每种最后存在的颜色能看到的有几段。
思路:
因为是区间,所以范围变成(l+1, r)。
原数组直接延迟操作。
最后将查询的位置对应到color数组上,统计答案。
代码:
#include <iostream> #include <memory.h> #include <vector> #include <map> #include <algorithm> #include <cstdio> using namespace std; typedef long long LL; const int MAXN = 8000 + 10; int segment[MAXN * 4]; int color[MAXN]; int res[MAXN]; void Push_Down(int root) { if (segment[root] != -1) { segment[root << 1] = segment[root]; segment[root << 1 | 1] = segment[root]; segment[root] = -1; } } void Update(int root, int l, int r, int ql, int qr, int c) { if (ql > r || l > qr) return; if (ql <= l && r <= qr) { segment[root] = c; return; } if (segment[root] == c) return; Push_Down(root); int mid = (l + r) / 2; Update(root << 1, l, mid, ql, qr, c); Update(root << 1 | 1, mid + 1, r, ql, qr, c); } void Query(int root, int l, int r) { if (segment[root] != -1) { for (int i = l;i <= r;i++) color[i] = segment[root]; return ; } if (l < r) { int mid = (l + r) / 2; Query(root << 1, l, mid); Query(root << 1 | 1, mid + 1, r); } } void Count() { int i = 1; while (i <= 8000) { if (color[i++] == -1) continue; while (i <= 8000 && color[i] == color[i - 1]) ++i; res[color[i - 1]]++; } } int main() { int n; while (~scanf("%d", &n)) { memset(segment, -1, sizeof(segment)); memset(color, -1, sizeof(color)); memset(res, 0, sizeof(res)); int l, r, c; for (int i = 1;i <= n;i++) { scanf("%d%d%d", &l, &r, &c); Update(1, 1, 8000, l + 1, r, c); } Query(1, 1, 8000); Count(); for (int i = 0;i <= 8000;i++) { if (res[i] != 0) printf("%d %d ", i, res[i]); } printf(" "); } return 0; }