poj 2777 Count Color(线段树 区间更新)

时间:2021-03-31 03:43:13

题目:http://poj.org/problem?id=2777

区间更新,比点更新多一点内容, 详见注释,  参考了一下别人的博客。。。。

参考博客:http://www.2cto.com/kf/201402/277917.html

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int maxn = + ; bool mark[];
struct node
{
int l, r, kind;
}tr[maxn<<]; void build(int t, int l, int r) //建树
{
tr[t].l = l;
tr[t].r = r;
tr[t].kind = ;
if(l == r) return;
int mid = (l+r)>>;
build(*t, l, mid);
build(*t+, mid+, r);
}
void update(int t, int l, int r, int cover) //区间颜色更新
{
if(tr[t].l == l&& tr[t].r == r) //找到区间改颜色
{
tr[t].kind = cover;
return;
}
if(tr[t].kind != && tr[t].kind != cover) //区间是纯色,而且不是目标颜色
{
tr[*t].kind = tr[t].kind;
tr[*t+].kind = tr[t].kind; //更新子树颜色
tr[t].kind = ; //标记为混合色
}
int mid = (tr[t].l + tr[t].r)>>;
if(r <= mid)
update(*t, l, r, cover);
else if(l > mid)
update(*t+, l, r, cover);
else //左右子树各有一段
{
update(*t, l, mid, cover);
update(*t+, mid+, r, cover);
}
}
void query(int t, int l, int r)
{
if(tr[t].kind > ) //该段为纯色,不用向下搜了
{
mark[tr[t].kind] = true;
return;
}
int mid = (tr[t].l + tr[t].r)>>;
if(r <= mid)
query(*t, l, r);
else if(l > mid)
query(*t+, l, r);
else
{
query(*t, l, mid);
query(*t+, mid+, r);
}
}
int main()
{
int n, color, m, i;
int a, b, c, sum;
char ch[];
scanf("%d%d%d", &n, &color, &m);
build(, , n);
while(m--)
{
scanf("%s",ch);
if(ch[] == 'C')
{
scanf("%d%d%d", &a, &b, &c);
if(a > b)
update(, b, a, c);
else
update(, a, b, c);
}
else
{
scanf("%d%d", &a, &b);
memset(mark, false, sizeof(mark));
if(a > b)
query(, b, a);
else
query(, a, b);
sum = ;
for(i = ; i <= color; i++)
{
if(mark[i])
{
sum += ;
//cout<<i<<endl;
}
}
printf("%d\n", sum);
}
}
return ;
}