ZOJ1610Count the Colors(线段树成段更新染色)
2017-03-14 16:57
33 查看
链接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610
题目大意:
在一条长度为8000的线段上染色,每次把区间[a,b]染成c颜色。显然,后面染上去的颜色会覆盖掉之前的颜色。
求染完之后,每个颜色在线段上有多少个间断的区间。
注意:
因为染色的是区间,是从最左边的向右开始染色,所以更新的时候左端点可以加1。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 8005;
int n, col[maxn<<2], vis[maxn<<2], ans[maxn];
void inline push_down(int rt)
{
col[rt<<1] = col[rt<<1|1] = col[rt];
col[rt] = -1;
}
void update(int rt, int left, int right, int l, int r, int data)
{
if(l <= left && right <= r)
{
col[rt] = data;
return;
}
if(col[rt] == data)
return;
if(col[rt] != -1)
push_down(rt);
int mid = (left + right) >> 1;
if(l <= mid)
update(rt<<1, left, mid, l, r, data);
if(r > mid)
update(rt<<1|1, mid+1, right, l, r, data);
}
void query(int rt, int left, int right)
{
if(col[rt] >= 0)
{
for(int i = left; i <= right; i++)
vis[i] = col[rt];
return;
}
if(left < right && col[rt] == -1)
{
int mid = (left+right) >> 1;
query(rt<<1, left, mid);
query(rt<<1|1, mid+1, right);
}
}
int main()
{
int u, v, w;
while(scanf("%d", &n) != EOF)
{
memset(col, -1, sizeof(col));
for(int i = 1; i <= n; i++)
{
scanf("%d%d%d", &u, &v, &w);
if(u >= v)
continue;
update(1, 1, 8000, u+1, v, w);
}
memset(vis, -1, sizeof(vis));
query(1, 1, 8000);
memset(ans, 0, sizeof(ans));
int i = 1;
while(i <= 8000)
{
int color = vis[i], j = i + 1;
if(color == -1)
{
++i;
continue;
}
while(vis[j] == color && j <= 8000)
++j;
++ans[color];
i = j;
}
for(int i = 0; i <= 8000; i++)
if(ans[i])
cout << i << " " << ans[i] << endl;
puts("");
}
return 0;
}
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610
题目大意:
在一条长度为8000的线段上染色,每次把区间[a,b]染成c颜色。显然,后面染上去的颜色会覆盖掉之前的颜色。
求染完之后,每个颜色在线段上有多少个间断的区间。
注意:
因为染色的是区间,是从最左边的向右开始染色,所以更新的时候左端点可以加1。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 8005;
int n, col[maxn<<2], vis[maxn<<2], ans[maxn];
void inline push_down(int rt)
{
col[rt<<1] = col[rt<<1|1] = col[rt];
col[rt] = -1;
}
void update(int rt, int left, int right, int l, int r, int data)
{
if(l <= left && right <= r)
{
col[rt] = data;
return;
}
if(col[rt] == data)
return;
if(col[rt] != -1)
push_down(rt);
int mid = (left + right) >> 1;
if(l <= mid)
update(rt<<1, left, mid, l, r, data);
if(r > mid)
update(rt<<1|1, mid+1, right, l, r, data);
}
void query(int rt, int left, int right)
{
if(col[rt] >= 0)
{
for(int i = left; i <= right; i++)
vis[i] = col[rt];
return;
}
if(left < right && col[rt] == -1)
{
int mid = (left+right) >> 1;
query(rt<<1, left, mid);
query(rt<<1|1, mid+1, right);
}
}
int main()
{
int u, v, w;
while(scanf("%d", &n) != EOF)
{
memset(col, -1, sizeof(col));
for(int i = 1; i <= n; i++)
{
scanf("%d%d%d", &u, &v, &w);
if(u >= v)
continue;
update(1, 1, 8000, u+1, v, w);
}
memset(vis, -1, sizeof(vis));
query(1, 1, 8000);
memset(ans, 0, sizeof(ans));
int i = 1;
while(i <= 8000)
{
int color = vis[i], j = i + 1;
if(color == -1)
{
++i;
continue;
}
while(vis[j] == color && j <= 8000)
++j;
++ans[color];
i = j;
}
for(int i = 0; i <= 8000; i++)
if(ans[i])
cout << i << " " << ans[i] << endl;
puts("");
}
return 0;
}
相关文章推荐
- zoj 1610 Count the Colors 线段树,成段更新染色
- ZOJ 1610 Count the Colors(线段树,成段更新染色)
- zoj 1610 Count the Colors(线段树)(成段更新染色)
- POJ训练计划2777_Count Color(线段树/成段更新/区间染色)
- zoj 1610 Count the Colors(线段树,成段更新染色)
- poj 2528 Mayor's posters(线段树,离散化,成段更新染色)
- POJ训练计划2777_Count Color(线段树/成段更新/区间染色)
- HDU 3974 Assign the task(dfs时间戳+线段树成段更新)
- ZOJ 1610 Count the Colors(线段树——区间更新)(成段染色)
- 线段树成段更新
- 【线段树成段更新成段查询模板】【POJ3468】A Simple Problem with Integerst
- BZOJ 2243 [SDOI2011]染色 树链剖分+LCA+区间合并线段树
- POJ 1436 (线段树 区间染色) Horizontally Visible Segments
- POJ 3468 A Simple Problem with Integers 线段树 (成段更新)
- HYSBZ 2243 染色(树链剖分 + 线段树区间合并)
- ZOJ 1610 Count the Colors (线段树:区间染色set,整体查询)
- 树状数组,线段树(区间成段更新,HDU 4267)
- [ACM] hdu 1698 Just a Hook (线段树,成段更新,懒惰标记)
- hdu1698 Just a Hook 线段树,成段更新
- 【codevs1191】数轴染色 线段树 区间修改+固定区间查询