ZOJ 1610Count the Colors 线段树区间染色问题
来源:互联网 发布:php笔试题及答案 编辑:程序博客网 时间:2024/04/27 21:02
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66989#problem/F
题意:给一个区间范围,然后逐步给某些区间染色,最后问能各种能看见的颜色的块数。典型的线段树染色问题,看了别人的代码不太能理解。但是想到了一个不错的思路。
解题思路:我们可以这样想,显然每条线段最后的颜色都由改线段最后一次的染色决定,如果我们把每一次染色都标记一个步数,显然每条线段的最后颜色就由其上面的区间中所包含的最大步数所决定,这样就好想多了,我们每一次染色就对目标区间插入一个步数,顺便记录下该步数所用的颜色,最后用O(n)的时间求出每个叶子的最后步数和颜色即可。
由于线段树最后的叶子一般都是一个点,而本题最小的单位是一条线段而不是一个点,所以我们把每一条线段看成一个点,建立线段树。
代码:
#include<iostream>#include<cstdio>#include<cstring>#define maxn 8010#define LL long longusing namespace std;struct node{ int l,r,w;//区间的左右端点,和该区间的最后一个染色步数}T[maxn*3];int n,col[maxn],A[maxn],cnt[maxn];void build(int L,int R,int o){ T[o].l=L;T[o].r=R;T[o].w=0; if(L==R) return; build(L,(L+R)/2,o*2); build((L+R)/2+1,R,o*2+1);}void add(int L,int R,int step,int o){ if(T[o].l>=L && T[o].r<=R) {T[o].w=step;return;} if(T[o].l==T[o].r) return; if(L>=T[o*2+1].l) add(L,R,step,o*2+1); else if(R<=T[o*2].r) add(L,R,step,o*2); else{ add(L,T[o*2].r,step,o*2); add(T[o*2+1].l,R,step,o*2+1); }}void dfs(int o,int Max){//dfs遍历线段树并求出叶子的颜色 Max=max(Max,T[o].w); if(T[o].l==T[o].r) {A[T[o].l]=col[Max];return;} dfs(o*2,Max); dfs(o*2+1,Max);}void disp(){ int t=-1; memset(cnt,0,sizeof(cnt)); for(int i=0;i<=8000;i++){//处理相连颜色的情况 if(A[i]==-1 || A[i]==t){t=A[i];continue;} t=A[i]; cnt[t]++; } for(int i=0;i<=8000;i++) if(cnt[i]) printf("%d %d\n",i,cnt[i]); printf("\n");}int main(){ //freopen("in.txt","r",stdin); while(cin>>n){ build(1,8000,1);//把每一线段看成一个端点,所以从1开始 int a,b,c; col[0]=-1; for(int i=1;i<=n;i++){ scanf("%d %d %d",&a,&b,&c); col[i]=c;//记录第i个输入的颜色 add(a+1,b,i,1);//这里以单位线段为一个点,插入一个步数 } memset(A,-1,sizeof(A));//-1表色没有染过色 dfs(1,0);//更新每个叶子的最后步数和颜色 disp();//输出答案 } return 0;}
0 0
- ZOJ 1610Count the Colors 线段树区间染色问题
- ZOJ 1610 Count the Colors (线段树区间染色)
- ZOJ 1610Count the Colors(线段树+区间染色)
- ZOJ 1610 Count the Colors(线段树区间染色)
- zoj 1610 Count the Colors 线段树区间更新——染色问题
- ZOJ 1610 Count the Colors 线段树 染色问题
- ZOJ 1610 Count the Colors(线段树——区间更新)(成段染色)
- zoj 1610 Count the Colors(线段树染色)
- ZOJ 1610Count the Colors 线段树_区间更新
- ZOJ 1610 Count the Colors(线段树区间更新)
- zoj 1610 Count the Colors(线段树 区间更新)
- ZOJ 1610 Count the Colors (线段树区间更新)
- zoj 1610 Count the Colors(线段树 区间更新)
- ZOJ 1610 Count the Colors(线段树 区间覆盖)
- zoj 1610 Count the Colors 线段树 区间更新
- ZOJ 1610 Count the Colors (线段树-区间覆盖)
- zoj 1610 Count the Colors (线段树区间覆盖)
- zoj 1610 Count the Colors 【区间覆盖 求染色段】
- Vijava 学习笔记之模板
- 常用数据库连接写法
- Mysql主从同步配置
- JSTL标签库的使用详解
- 介绍几种大型的Oracle/SQL Server数据库免费版
- ZOJ 1610Count the Colors 线段树区间染色问题
- [LeetCode] Binary Tree Right Side View
- Ant: 使用外部的tasks
- SX1276调试总结
- rm命令详解
- 排列组合公式
- Linux文件系统——全方位掌握
- iOS中frame和bounds的区别
- 如何在QML应用中使用Javascript来解析XML