Time Limit: 2 Seconds Memory Limit: 65536 KB
Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones.
Your task is counting the segments of different colors you can see at last.
Input
The first line of each data set contains exactly one integer n, 1 <= n <= 8000, equal to the number of colored segments.
Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces:
x1 x2 c
x1 and x2 indicate the left endpoint and right endpoint of the segment, c indicates the color of the segment.
All the numbers are in the range [0, 8000], and they are all integers.
Input may contain several data set, process to the end of file.
Output
Each line of the output should contain a color index that can be seen from the top, following the count of the segments of this color, they should be printed according to the color index.
If some color can't be seen, you shouldn't print it.
Print a blank line after every dataset.
Sample Input
5
0 4 4
0 3 1
3 4 2
0 2 2
0 2 3
4
0 1 1
3 4 1
1 3 2
1 3 1
6
0 1 0
1 2 1
2 3 1
1 2 0
2 3 0
1 2 1
Sample Output
1 1
2 1
3 1
1 1
0 2
1 1
题意:
有N(1到8000)种颜色,给出N行a,b,c,表示a到b这个区间填充c颜色,N次输入的颜色可以覆盖前面的颜色,最后输出能看见的颜色中,一共有几段(颜色要按从小到大输出)。
思路:
用线段树延迟标记。
AC:
#include<cstdio> #include<string.h> #include<map> #define MAX (8000+5) #define INT 10000 using namespace std; typedef struct { int l; //左边界 int r; //右边界 int co; //颜色域 int ad; //标记域 }node; node no[MAX*3]; int col[MAX],from[MAX],to[MAX]; int fin[MAX]; //fin用来保存这条线段最后的颜色 void build(int from,int to,int i) { int mid=(from+to)/2; no[i].l=from; no[i].r=to; no[i].ad=-1; no[i].co=-1; if(to-from==1) return; build(from,mid,2*i); build(mid,to,2*i+1); } void add(int from,int to,int i,int c) { int mid=(no[i].l+no[i].r)/2; if(from==no[i].l&&to==no[i].r) { no[i].ad=c; return; } else { if(no[i].ad!=-1) { no[i].co=no[i].ad; no[2*i].ad=no[i].ad; no[2*i+1].ad=no[i].ad; no[i].ad=-1; } if(from>=mid) add(from,to,2*i+1,c); if(to<=mid) add(from,to,2*i,c); if(from<mid&&to>mid) { add(from,mid,2*i,c); add(mid,to,2*i+1,c); } } } void find(int i) { int mid=(no[i].l+no[i].r)/2; if(no[i].r-no[i].l==1) { if(no[i].ad!=-1) no[i].co=no[i].ad; fin[no[i].l]=no[i].co; } else { if(no[i].ad!=-1) { no[i].co=no[i].ad; no[2*i].ad=no[i].ad; no[2*i+1].ad=no[i].ad; no[i].ad=-1; } find(2*i); find(2*i+1); } } int main() { int n; while(scanf("%d",&n)!=EOF) { int ma=-1,mi=INT; memset(fin,-1,sizeof(fin)); for(int i=1;i<=n;i++) { scanf("%d%d%d",&from[i],&to[i],&col[i]); if(from[i]<mi) mi=from[i]; if(to[i]>ma) ma=to[i]; } //建树 build(mi,ma,1); //添加颜色 for(int i=1;i<=n;i++) add(from[i],to[i],1,col[i]); //查找颜色段 find(1); //用map关联容器存储最后结果 map<int,int> m; m.clear(); for(int i=mi;i<=ma-1;i++) { if(fin[i]==-1) continue; if(i==mi&&fin[mi]!=-1) m[fin[i]]++; if(i>mi&&fin[i]!=fin[i-1]) m[fin[i]]++; } //输出结果 map<int,int>::iterator it; for(it=m.begin();it!=m.end();it++) printf("%d %d\n",it->first,it->second); printf("\n"); } return 0; }
总结:
1.线段树的区间要想清楚如何分法;
2.查询完后,想清楚要如何判断有几段;
相关推荐
zoj 1610 Count the Colors.md
线段树模板 线段树是一种重要的数据结构,广泛应用于算法竞赛和实际问题中。下面我们将详细介绍线段树的定义、性质、时间复杂度和应用。 线段树的定义 线段树是一种二叉树,每个结点对应一个线段[a, b]。线段树...
1. **节点定义**:`ITREE_NODE` 结构体定义了一个线段树节点,包括左右子节点指针、区间边界(`left`, `right`)、区间测量值(`measure`)、区间内的元素计数(`count`)、以及与区间相关的线数(`lines`)和边界...
### 线段树详解 #### 一、线段树定义与结构 **定义:** 线段树是一种高效的数据结构,常被用于处理区间查询或更新的问题。它是一棵二叉树,其中每个节点代表一个特定的区间。具体来说: - **叶子节点**:代表一个...
2. 对于每个点,从根节点开始遍历线段树,更新 count 字段,得到点在各线段中出现的次数,时间复杂度为 O(M*log(MAX-MIN)),其中 M 是点的数量。 总结下来,线段树的主要优点是它提供了对区间操作的高效处理,尤其...
`:定义线段树的结构体,其中`left`和`right`表示节点所覆盖的区间左右边界,`count`表示该区间内的元素数量。 2. **线段树构建**: - `void make_tree(int l, int r, int loc)`:函数用于构建线段树。 - 初始化...
Count the frequency distribution of units digits
print(f'The file has {line_count} lines.') ``` 这个脚本打开文件,读取所有行并计算其数量。 4. **Java**:在Java中,你可以使用BufferedReader类来迭代文件的每一行,如下所示: ```java import java.io....
"count设计"通常指的是计数器的设计,这是一种基本的数字逻辑电路,用于实现数字的累加或递增。在本资料包中,"lekko_vhdl_count"可能是一个示例项目或者代码库,它包含了使用VHDL编写的计数器设计。 计数器是数字...
layui laypage插件如何通过ajax返回动态count值,然后重置laypage count值
Matlab codes for analyzing the size distribution of nanoparticles
android-count-the-days android project in kotlin to count the days from a time point. MIT licensed. I needed an app that would count days since a date and days until. The current apps on the market, ...
count++) { value_buf[count] = get_ad(); delay(); } // 排序过程省略... return value_buf[(N - 1) / 2]; } ``` #### 2.3 简单算术平均值滤波法 - **定义**: 连续读取N个数值,并计算其平均值作为最终...
在给定的“count-the-number-of-the-words.zip_The Count”项目中,任务是设计一个名为`Word`的类,该类能够存储字符串并计算其中的单词总数。这个任务涉及到面向对象编程的概念,如类的定义、成员变量和方法。 ...
cone low in matlab for count MATLAB program to calculate the size of the law of the conical tank A time of emptying the tank
count++) { value_buf[count] = get_ad(); delay(); } for (j = 0; j ; j++) { for (i = 0; i ; i++) { if (value_buf[i] > value_buf[i + 1]) { temp = value_buf[i]; value_buf[i] = value_buf[i + 1]; ...
fping-exporter 允许您使用 fping 和 prometheus 运行测量...fping_rtt_count:测量的延迟数(成功的探测) fping_rtt_sum:测量延迟的总和 fping_rtt:测量延迟的摘要 更多详情、使用方法,请下载后阅读README.md文件
count++){memset(a[count],1,N*sizeof(double));}这样可以确保每个元素都被正确地初始化。 此外,在free内存时,也需要注意正确地释放每个元素的内存空间,例如:for(count=0;count;count++){free(a[count]);free(L...