POJ 2777 count color

这篇博客介绍了一种利用二进制表示颜色并结合线段树的数据结构来高效处理两种操作:一是将指定区间内的元素染成特定颜色,二是查询指定区间内颜色的种类数。代码实现中,通过建立线段树并更新、查询节点信息,实现了对颜色变化的快速响应。这种方法适用于颜色种类较少且区间操作频繁的场景。
摘要由CSDN通过智能技术生成

题目:

两种操作,一种是将 a 到 b 染成某一种颜色,第二种是询问a 到 b 有多少种颜色。颜色小于30种,长度不超过1e5。

思路:

因为题目明确表明颜色只有30种,所以可以用一个int表示所有的颜色(二进制表示),再用线段树进行优化就可以很轻松的过掉。

代码:

#include <cstdio>
#define MaxN 100001
using namespace std;

int color[ 31 ] = { 0 };

typedef struct {
	int left, right;
	int sum;
	int lazy;
} node;
node tree[ MaxN * 4 ];

void bulittree( int po, int left, int right ) {
	tree[ po ].left = left;
	tree[ po ].right = right;
	tree[ po ].lazy = 0;
	tree[ po ].sum = 1;
	if ( left == right ) {
		return;
	} else {
		int middle = ( left + right ) / 2;
		bulittree( po * 2, left, middle );
		bulittree( po * 2 + 1, middle + 1, right );
	}
}

void pushup( int po ) {
	tree[ po ].sum = tree[ po * 2 ].sum | tree[ po * 2 + 1 ].sum;
}

void pushdown( int po ) {
	if ( tree[ po ].lazy ) {
		tree[ po * 2 ].sum = tree[ po ].lazy;
		tree[ po * 2 + 1 ].sum = tree[ po ].lazy;
		tree[ po * 2 ].lazy = tree[ po ].lazy;
		tree[ po * 2 + 1 ].lazy = tree[ po ].lazy;
		tree[ po ].lazy = 0;
	}
}

void update( int po, int left, int right, int need ) {
	if ( tree[ po ].left >= left && tree[ po ].right <= right ) {
		tree[ po ].sum = color[ need ];
		tree[ po ].lazy = color[ need ];
	} else {
		pushdown( po );
		int middle = ( tree[ po ].left + tree[ po ].right ) / 2;
		if ( left <= middle ) {
			update( po * 2, left, right, need );
		}
		if ( right > middle ) {
			update( po * 2 + 1, left, right, need );
		}
		pushup( po );
	}
}

int query( int po, int left, int right ) {
	if ( tree[ po ].left >= left && tree[ po ].right <= right ) {
		return tree[ po ].sum;
	} else {
		pushdown( po );
		int middle = ( tree[ po ].left + tree[ po ].right ) / 2;
		int ans = 0;
		if ( left <= middle )
			ans |= query( po * 2, left, right );
		if ( right > middle )
			ans |= query( po * 2 + 1, left, right );
		return ans;
	}
}

int main( void ) {
	int N, M, T;
	int left, right, need, answer;
	int i, j;
	char test;
	j = 1;
	for ( i = 1; i <= 30; i ++ ) {
		color[ i ] = j;
		j *= 2;
	}
	scanf("%d %d %d", &N, &T, &M );
	getchar( );
	bulittree( 1, 1, N );
	while ( M -- ) {
		scanf("%c", &test );
		switch ( test ) {
			case 'C' : {
				scanf("%d %d %d", &left, &right, &need );
				if ( left > right ) {
					left ^= right;
					right ^= left;
					left ^= right;
				}
				update( 1, left, right, need );
				getchar( );
				break;
			}
			case 'P' : {
				scanf("%d %d", &left, &right );
				getchar( );
				if ( left > right ) {
					left ^= right;
					right ^= left;
					left ^= right;
				}
				answer = 0, j = query( 1, left, right );
				while ( j ) {
					if ( j % 2 )
						answer ++;
					j /= 2;
				}
				printf("%d\n", answer );
				break;
			}
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值