#include <iostream> using namespace std; #define MAX 16000 int left_child[MAX],right_child[MAX],left_bound[MAX],right_bound[MAX],color[MAX],bj[MAX]; int node=0,res[MAX],temp; void clear(int index) { color[index]=bj[index]; bj[left_child[index]]=bj[index]; bj[right_child[index]]=bj[index]; bj[index]=-1; } void construct(int left,int right) { int index; ++node; index=node; left_bound[index]=left; right_bound[index]=right; color[index]=-2;//未着色 bj[index]=-1;//未标记 if(left+1<right) { int mid=(left+right)/2; left_child[index]=node+1; construct(left,mid); right_child[index]=node+1; construct(mid,right); } } void insert(int index,int left,int right,int col) { if(bj[index]!=-1) clear(index); if(color[index]==col)//一个结点要不是全色,则是混色. 如果是全色且颜色相同就不必染了,因为所有的子段都是这个颜色.如果是混色,则需要去子段里找全色或者找完全覆盖的子段去染色. return; if(left<=left_bound[index]&&right>=right_bound[index])// 如果完全覆盖线段,那么bj[]=col,以后访问时调用clear()更新自己与孩子结点的颜色 { bj[index]=col;//bj的理解是关键,只有当一个线段完全着同一色时才会设置bj,而且该线段的子线段都应该与bj[index]具有相同着色,所以在下一次访问index之下的结点时,会经过index,并且clear(index) //可以让该线段的颜色bj传递给子线段bj。 这时候如果要染色的线段就是这个线段,那么直接覆盖bj[index],下一次访问该线段或者子线段时调用clear()就可以完成颜色更新,而且子线段的bj也受到了修改。 //如果线段被部分覆盖,那么说明当前的线段是由子线段的着色混合造成的,所以对于子线段进行颜色的插入,并且由于clear(index),所以子线段的标记bj[]也都更新为父线段的原先颜色,此时将父线段 //颜色设置为混合,则再次访问这个线段时就会去子线段里找,并且在子线段里clear()得到了从而继承父线段的颜色或者完全覆盖子线段颜色. } else //如果部分覆盖 { if(left_bound[index]+1<right_bound[index])//非叶子,如果是叶子则一定在else之上的语句被覆盖 { color[index]=-1;//表示该线段不是整体一个颜色,是由各个子段颜色混合而成 int mid=(left_bound[index]+right_bound[index])/2; if(left<mid) insert(left_child[index],left,right,col); if(right>mid) insert(right_child[index],left,right,col); } } } void search(int index) { if(bj[index] != -1) clear(index); if(color[index] != -1) { if(color[index] != temp){ if(color[index] >= 0) res[color[index]]++; temp = color[index]; } } else { search(left_child[index]); search(right_child[index]); } } int main() { node=0; memset(left_child,0,sizeof(left_child)); memset(left_child,0,sizeof(right_child)); int n,left,right,col; construct(1,8000); cin>>n; for(int i=1;i<=n;++i) { cin>>left>>right>>col; insert(1,left,right,col); } search(1); for(int i=0;i<8001;++i) { if(res[i]) { cout<<i<<res[i]<<endl; } } } 详细资料在这里边 http://www.cppblog.com/MemoryGarden/archive/2009/04/11/79565.html