poj--2777状态压缩线段树

本博客介绍了一个利用二进制和线段树解决的颜色计数问题。在一个长木板上,通过区间染色操作和查询不同颜色数量,采用状态压缩技巧,将颜色表示为二进制位,实现高效区间更新与查询。适合学习数据结构和算法优化的读者。

Count Color
Time Limit: 1000MS

Memory Limit: 65536K

Description
Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.

There is a very long board with length L centimeter, L is a positive integer, so we can evenly divide the board into L segments, and they are labeled by 1, 2, … L from left to right, each is 1 centimeter long. Now we have to color the board - one segment with only one color. We can do following two operations on the board:

  1. “C A B C” Color the board from segment A to segment B with color C.
  2. “P A B” Output the number of different colors painted between segment A and segment B (including).

In our daily life, we have very few words to describe a color (red, green, blue, yellow…), so you may assume that the total number of different colors T is very small. To make it simple, we express the names of colors as color 1, color 2, … color T. At the beginning, the board was painted in color 1. Now the rest of problem is left to your.
Input
First line of input contains L (1 <= L <= 100000), T (1 <= T <= 30) and O (1 <= O <= 100000). Here O denotes the number of operations. Following O lines, each contains “C A B C” or “P A B” (here A, B, C are integers, and A may be larger than B) as an operation defined previously.
Output
Ouput results of the output operation in order, each line contains a number.
Sample Input
2 2 4
C 1 1 2
P 1 2
C 2 2 2
P 1 2
Sample Output
2
1
/这题很巧妙的利用了二进制,0010就代表第二种颜色,如果与0001进行或运算,就变成了0011.这样用1逐位与运算就计算出来了颜色数为2,对区间操作用lazy标记/

#include<iostream>
#include<algorithm>
#include<string.h>
#include<cstdio>
using namespace std;
#define clean(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define maxn 100005
int tree[maxn<<2],lazy[maxn<<2];
/*状态压缩,利用二进制表示这段是什么颜色,0010表示这段是颜色二*/
void push_up(int rt)
{
	tree[rt]=tree[rt<<1] | tree[rt<<1|1]; //逐位与运算 
}
void push_down(int rt)
{
	if(lazy[rt])
	{
		tree[rt<<1]=tree[rt<<1|1]=lazy[rt];
		lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
		lazy[rt]=0;
	}
}
void build(int l,int r,int rt)
{
	lazy[rt]=0;
	if(l==r){
		tree[rt]=1;
		return ;
	}
	int mid=(l+r)>>1;
	build(lson);
	build(rson);
	push_up(rt); 
}
void update(int l,int r,int rt,int tl,int tr,int x)
{
	if(r<tl || l>tr) return ;
	if(l>=tl && r<=tr){
		int color=1<<(x-1);
		tree[rt]=lazy[rt]=color;
		return ;
	}
	push_down(rt);
	int mid=(l+r)>>1;
	if(mid<tr)
	update(rson,tl,tr,x);
	if(mid>=tl)
	update(lson,tl,tr,x);
	push_up(rt);
}
int query(int l,int r,int rt,int tl,int tr)
{
	if(r<tl || l>tr) return 0;
	if(l>=tl && r<=tr)
	return tree[rt];
	int mid=(l+r)>>1;
	push_down(rt);
	return query(lson,tl,tr) | query(rson,tl,tr);
}
int number(int x)
{
	int cnt=0;
	while(x)
	{
		if(x&1) cnt++;
		x>>=1;
	}
	return cnt;
}
int main()
{
	//初始时都为颜色1 
	int n,t,m; //长度,颜色数,操作 
	char ch[3];
	while(~scanf("%d%d%d",&n,&t,&m))
	{
		build(1,n,1);
		while(m--)
		{
			scanf("%s",ch);
			getchar();
			if(ch[0] == 'C')
			{
				int l,r,x;
				if(l>r) swap(l,r);
				scanf("%d%d%d",&l,&r,&x);
				getchar();
				update(1,n,1,l,r,x);
			}
			else
			{
				int l,r;
				scanf("%d%d",&l,&r);
				getchar();
				if(l>r) swap(l,r);
				int ans=query(1,n,1,l,r);
				ans=number(ans);
				printf("%d\n",ans);
			}
		}
		
	}
	return 0;
}

内容概要:本文系统梳理了多个科研领域的前沿研究与技术实现,重点涵盖FDTD方法中的完美匹配层(PML)研究,以及Matlab/Simulink在电磁、电力、控制、通信、信号处理、图像处理、路径规划、能源系统优化等领域的仿真与算法实现。文中列举了大量基于Matlab和Python的科研案例,如风电功率预测、负荷预测、无人机三维路径规划、电池系统故障诊断、雷达模拟、通信编码、微电网优化调度等,并强调结合智能优化算法(如粒子群、遗传算法、深度学习等)提升系统性能。同时,提供了丰富的代码资源与仿真模型,涵盖永磁同步电机控制、逆变器设计、多智能体任务分配、虚拟电厂调度等复杂系统,助力科研人员快速开展复现实验与创新研究。; 适合人群:具备一定编程基础,熟悉Matlab/Python工具,从事电气工程、自动化、通信、人工智能、新能源、控制科学等相关领域研究的研发人员及研究生。; 使用场景及目标:① 学习并实现FDTD仿真中的PML边界条件以有效抑制数值反射;② 掌握Matlab/Simulink在多物理场建模、控制系统设计与优化算法中的综合应用;③ 借助提供的代码资源完成科研复现、课程设计、竞赛项目或工程原型开发; 阅读建议:此资源以科研实战为导向,不仅提供理论方法,更强调代码实现与仿真验证。建议读者结合自身研究方向,按目录顺序查阅相关模块,下载配套代码进行调试与二次开发,以达到学以致用、融会贯通的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_橙月_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值