by 华师小刚
需要注意:
1.线段树数组开400000个
2.初始颜色都为1
3.有多组测试数据
4.用STL记录答案会超时
5.输入是给出x块到y块,不是区间,而且x的序号可能大于y的序号。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;
const int N = 400000 + 10;
bool vis[31];
struct Node
{
Node():l(-1), r(-1), k(1) {}
int l, r;
int k;//-1表示该区间未被完全覆盖
}st[N];
void BuildTree(int pos, int a, int b)
{
st[pos].l = a;
st[pos].r = b;
st[pos].k = 1;
if (b - a == 1) return;
int mid = (a + b) / 2;
BuildTree(pos * 2 + 1, a, mid);
BuildTree(pos * 2 + 2, mid, b);
}
void modify(int pos, int a, int b, int c) //区间(a, b)涂 c
{
if (st[pos].l == a && st[pos].r == b)
{
st[pos].k = c;
return;
}
if (st[pos].k > 0)//将信息往下传
{
st[pos * 2 + 1].k = st[pos].k;
st[pos * 2 + 2].k = st[pos].k;
}
st[pos].k = -1;//表示该节点没被完全覆盖
int mid = (st[pos].l + st[pos].r) / 2;
if (b <= mid)
{
modify(pos * 2 + 1, a, b, c);
}
else if (a >= mid)
{
modify(pos * 2 + 2, a, b, c);
}
else
{
modify(pos * 2 + 1, a, mid, c);
modify(pos * 2 + 2, mid, b, c);
}
}
void count(int pos, int a, int b)
{
if (st[pos].k != -1 && a >= st[pos].l && b <= st[pos].r)
{
vis[st[pos].k] = 1;
return;
}
int mid = (st[pos].l + st[pos].r) / 2;
if (b <= mid)
{
count(pos * 2 + 1, a, b);
}
else if (a >= mid)
{
count(pos * 2 + 2, a, b);
}
else
{
count(pos * 2 + 1, a, mid);
count(pos * 2 + 2, mid, b);
}
}
void init()
{
for (int i = 1; i <= 30; ++i)
{
vis[i] = 0;
}
}
int main()
{
int L, T, O;
while (scanf("%d%d%d", &L, &T, &O) != EOF)
{
BuildTree(0, 0, L);
char op[2];
for (int i = 1; i <= O; ++i)
{
scanf("%s", &op);
if (op[0] == 'C')
{
int x, y, c;
scanf("%d%d%d", &x, &y, &c);
if (x > y) swap(x, y);
modify(0, x - 1, y, c);
continue;
}
init();
int x, y;
scanf("%d%d", &x, &y);
if (x > y) swap(x, y);
count(0, x - 1, y);
int res = 0;
for (int i = 1; i <= 30; ++i)
{
if (vis[i] == 1) res++;
}
printf("%d\n", res);
}
}
return 0;
}
测试数据:
10 4 5 C 2 1 3 C 9 10 2 C 5 5 4 P 1 5 P 2 2 12 5 10 C 3 2 4 C 5 4 2 P 6 5 C 1 2 2 C 2 3 2 C 4 4 1 P 2 3 P 7 7 C 8 12 5 P 1 12 6 7 4 C 1 6 2 P 1 5 C 4 2 7 P 6 1 5 3 5 C 1 3 2 P 2 4 C 3 5 3 P 1 5 P 3 4 答案: 3 1 2 1 1 3 1 2 2 2 1