ZOJ 1610 Count the Colors 线段树 染色问题

做法:在udate之后可以直接把线段树上的信息映射到一个数组上考虑

#include<cstdio>
#include<cstring>
#define left l,m,x<<1
#define right m+1,r,x<<1|1
const int LMT=16002;
int cov[LMT<<2],seg[LMT],ans[LMT];
//映射法
void init(void)
{
	memset(cov,-1,sizeof(cov));
	memset(seg,-1,sizeof(seg));
	memset(ans,0,sizeof(ans));
}
void cut(int x)
{
	if(cov[x]!=-1)
	{
		cov[x<<1]=cov[x<<1|1]=cov[x];
		cov[x]=-1;
	}
}
void update(int co,int L,int R,int l,int r,int x)
{
	if(L<=l&&r<=R)
	{
		cov[x]=co;
		return ;
	}
	cut(x);
	int m=(l+r)>>1;
	if(L<=m)update(co,L,R,left);
	if(R>m)update(co,L,R,right);
}
void query(int l,int r,int x)//线段树射到区间上
{
	if(cov[x]!=-1)
	{
		int i=l;
		for(;i<=r;i++)seg[i]=cov[x];
		return;
	}
	if(l==r)return;
	int m=(l+r)>>1;
	query(left);
	query(right);
}
int main(void)
{
	int n,l,r,co,i,j;
	while(~scanf("%d",&n))
	{
		init();
		for(i=1;i<=n;i++)
		{
			scanf("%d%d%d",&l,&r,&co);
			l++;r++;
			l<<=1;r<<=1;
			update(co,l,r,1,LMT-1,1);
		}
		query(1,LMT-1,1);
		for(int i=1;i<LMT;)
			if(seg[i]!=-1)
			{
				j=i;ans[seg[i]]++;
				while(j<LMT&&seg[j]==seg[i])j++;
				i=j;
			}
			else i++;
        for( i=0;i<=8000;i++)
			if(ans[i])printf("%d %d\n",i,ans[i]);
			printf("\n");
	}
	return 0;
}


你可能感兴趣的:(ZOJ 1610 Count the Colors 线段树 染色问题)