链接: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\n", i, res[i]);
}
printf("\n");
}
return 0;
}