#include<stdio.h> #include<string.h> #include<stdlib.h> #define N 8000 int flag; int num[N+1]={0}; struct intervaltree { int l,r,cover; struct intervaltree *lchild,*rchild; }; void initial(struct intervaltree *T)//可以不要了,建树和统计的时候就会将其初始化了 { if(T==NULL) return ; T->cover=-1; initial(T->lchild); initial(T->rchild); } struct intervaltree *tcreat(struct intervaltree *T,int left,int right) { T=(struct intervaltree *)malloc(sizeof(struct intervaltree)); T->l=left; T->r=right; T->cover=-1; if(right-left==1) { T->lchild=T->rchild=NULL; return T; } T->lchild=tcreat(T->lchild,left,(left+right)/2); T->rchild=tcreat(T->rchild,(left+right)/2,right); return T; } void coverleave(struct intervaltree *T,int color) { if(T==NULL) return ; T->cover=color; coverleave(T->lchild,color); coverleave(T->rchild,color); } void changcolor(struct intervaltree *T,int a,int b,int color) { int mid; if(T->cover==color) return ;//如果已经涂了形同的颜色了,就不再深入里面了 if(a<=T->l&&T->r<=b) { //T->cover=color; //if(T->lchild!=NULL) coverleave(T,color);//如果染色的不是叶子结点,则把他的孩子全部染成同样的颜色 return ; } mid=(T->l+T->r)/2; if(b<=mid) changcolor(T->lchild,a,b,color); else if(a>=mid) changcolor(T->rchild,a,b,color); else { changcolor(T->lchild,a,mid,color); changcolor(T->rchild,mid,b,color); } if(T->lchild!=NULL)//如果有孩子,则看颜色能不能合并 { if((T->lchild->cover==T->rchild->cover)&&(T->lchild->cover)!=-1) T->cover=T->lchild->cover; else T->cover=-1; } } void statistic(struct intervaltree *T) { if(T==NULL) return ; if(T->cover!=-1) { if(flag!=T->cover) { num[T->cover]++; flag=T->cover; } coverleave(T,-1);//统计过后将颜色檫除 return ; } if(T->lchild==NULL)//遍历到非空未涂色结点,则说明上一次的统计已经被隔开,和下一次统计不再是相邻的区间了 { flag=-1; return ; } statistic(T->lchild); statistic(T->rchild); } int main() { int n,i,start,end,color; struct intervaltree *T; T=tcreat(T,0,N); while(scanf("%d",&n)!=EOF) { //initial(T); for(i=0;i<n;i++) { scanf("%d %d %d",&start,&end,&color); changcolor(T,start,end,color); } flag=-1; statistic(T); for(i=0;i<=N;i++) if(num[i]!=0) { printf("%d %d\n",i,num[i]); num[i]=0; } printf("\n"); } return 0; } /*当同样的颜色位于不同的子树的时候,由于无法合并颜色,所以统计的时候会多加 2 0 1 0 2 3 0 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 0 2 1 1 2 1 3 1 1 1 0 2 1 1 #include<iostream> #include<cstdio> #include<string.h> using namespace std; int res[8010]; int nc; int n,s,e,c; class node { public: int left,right; node* lch; node* rch; int color;//>=0 singal -1:uncolored -2:muti-colored node(int start,int end) { this->left=start; this->right=end; this->lch=NULL; this->rch=NULL; this->color=-1; } void creatTree(node*root) { int end=root->right; int start=root->left; if(end-start>1) { node* lt=new node(start,(start+end)/2); node* rt=new node((start+end)/2,end); root->lch=lt; root->rch=rt; creatTree(lt); creatTree(rt); } } void insert(node*root,int start,int end,int color) { if((start==root->left&&end==root->right)||color==root->color) { root->color=color; return; } if(root->color>=0) { root->lch->color=root->color; root->rch->color=root->color; } root->color=-2; int mid=(root->left+root->right)/2; if(end<=mid) { insert(root->lch,start,end,color); } else if(start>=mid) { insert(root->rch,start,end,color); } else { insert(root->lch,start,mid,color); insert(root->rch,mid,end,color); } } void count(node*root) { if(root->color>=0&&nc!=root->color) { nc=root->color; ++res[nc]; } else if(root->color==-2) { count(root->lch); count(root->rch); } else { nc=root->color; } } }; node* createTree(int start,int end) { node* tmp=new node(start,end); if(end-start>1) { tmp->lch=createTree(start,(start+end)/2); tmp->rch=createTree((start+end)/2,end); } return tmp; } int average(int a,int b) { int r=(a&b)+((a^b)>>1); cout<<r<<endl; } int main() { freopen("e:\\zoj\\zoj_1610.txt","r",stdin); while(cin>>n) { //node* tree=createTree(0,8010); node*tree=new node(0,8010); tree->creatTree(tree); memset(res,0,sizeof(res)); nc=-1; while(n--) { scanf("%d%d%d",&s,&e,&c); tree->insert(tree,s,e,c); } tree->count(tree); for(int i=0;i<8010;i++) if(res[i]) printf("%d %d\n",i,res[i]); printf("\n"); } return 0; } */