#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;
}
*/