[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;
}
给了每一线段的颜色,存在颜色覆盖,求表面上看能看到的颜色种类和各种颜色的段数
#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;
}
相关文章推荐
- 线段树专题—ZOJ1610 Count the Colors
- ZOJ 1610 Count the Colors(线段树 区间覆盖)
- 线段树专题—ZOJ1610 Count the Colors
- ZOJ 1610——Count the Colors——————【线段树区间替换、求不同颜色区间段数】
- Count the Colors 数颜色 离散化+线段树
- zoj 1610 Count the Colors (线段树区间覆盖)
- Count the Colors ZOJ - 1610 线段树区间覆盖
- Count the Colors(线段树,找颜色段条数)
- ZOJ 题目1610 Count the Colors(线段树求颜色及有多少段)
- 【算法系列学习】线段树 单点覆盖,区间查询最大值 [kuangbin带你飞]专题七 线段树 B - I Hate It
- ZOJ 1610 Count the Colors (线段树-区间覆盖)
- ZOJ 1610 Count the Colors(线段树,区间覆盖,单点查询)
- zoj1610 Count the Colors(线段树)
- ZOJ - 1610 Count the Colors (线段树单点查询 区间更新)
- [kuangbin带你飞]专题七 线段树 A - 敌兵布阵 (单点修改,区间求和)
- [kuangbin带你飞]专题七 线段树 H HDU4027
- ZOJ 1610 Count the Colors(线段树——区间更新)(成段染色)
- F - Count the Colors - zoj 1610(区间覆盖)
- 【算法系列学习】线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵
- [kuangbin带你飞]专题十四 数论基础-C - Aladdin and the Flying Carpet