您的位置:首页 > 其它

[kuangbin带你飞]专题七 线段树 F - Count the Colors(颜色覆盖)

2017-10-01 18:09 519 查看
https://vjudge.net/contest/66989#problem/F

给了每一线段的颜色,存在颜色覆盖,求表面上看能看到的颜色种类和各种颜色的段数

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lid (id << 1)
#define rid (id << 1 | 1)
using namespace std;
const int maxn = 8005;
struct node
{
int l, r, c;
}tr[maxn*4];
int cnt[maxn], temp;
void push_down(int id)
{
if(tr[id].c!=-1)
{
tr[lid].c=tr[rid].c=tr[id].c;
tr[id].c=-1;
}
}
void Build (int id, int l, int r)
{
tr[id].l = l;tr[id].r = r;tr[id].c = -1;
if (l== r-1) return ;
else{
int mid=(l+r)>>1;
Build (id<<1, l, mid);
Build (id<<1|1, mid, r);
}
}
void update (int id, int l, int r, int c)
{//区间更新,
if (l==tr[id].l && tr[id].r==r) tr[id].c = c;
else{
push_down(id);
int mid = (tr[id].l+tr[id].r)>>1;
if (r <= mid) update (lid, l, r, c);
else if (l >= mid) update (rid, l, r, c);
else
{
update (lid, l, mid, c);
update (rid, mid, r, c);
}
}
}
void Count (int id)
{
if (tr[id].c != -1)
{//当前区间裸露在外面
if (tr[id].c != temp)//当前区间没有被统计过
cnt[tr[id].c] ++;
temp = tr[id].c;
return ;
}
if (tr[id].l == tr[id].r-1)
{//返回未被覆盖的区间,否则会栈溢出
temp = -1;
return ;
}
Count (lid);
Count (rid);
}
int main ()
{
int n, m;
while (scanf("%d",&n) != EOF)
{
Build (1,0,maxn);
while (n --)
{
int x, y, c;
scanf ("%d %d %d", &x, &y, &c);
update (1, x, y, c);
}
temp = -1;
memset (cnt,0,sizeof(cnt));
Count(1);
for (int i=0;i<maxn; i++)
if (cnt[i])
printf ("%d %d\n",i,cnt[i]);
printf ("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: