HDU 3397 Sequence operation (区间合并 )

本文详细记录了作者在学习线段树过程中遇到的一个难题及解决过程。通过此题,不仅展示了线段树的构建和查询操作,还深入讨论了如何处理区间修改与合并等问题。代码实现注重细节,为读者提供了宝贵的参考。

    刚开始学习线段树,没想到就碰到这样的题,由于太弱,搞了整整一天和一早上,真是充满了血与泪,但起码是自己一点点写出来的,值得。另外,由此题注意到写数据结构的题,代码的风格重要,这方面也要下点功夫。因为一个细节DEBUG花了好久,数据有些繁琐,细节比较多。下面是代码。

/*
结点需要保存的变量有lmax1,rmax1,sum1,mx1.分别代表从左数最大连续1的个数,从右数最大连续1的个数,1的总个数,期中最大的1连续个数.
					lmax0....同理
mode 代表延迟标记的状态,这里我定义0:无,1:操作0,2:操作1,3:操作2.		
L,R则代表结点区间范围。	
*/
#include <iostream>
using namespace std;
int data[200000];
struct node{
	int L,R;
	int lmax1,rmax1,sum1,mx1;
	int lmax0,rmax0,sum0,mx0;
	int mode;
	int dis(){return  R-L+1;}	//节点的区间大小
	int mid(){return (L+R)/2;}	//取中
	void set_1(){lmax1=dis(),rmax1=dis(),sum1=dis(),mx1=dis(),lmax0=0,rmax0=0,sum0=0,mx0=0;}	//操作1
	void set_0(){lmax0=dis(),rmax0=dis(),sum0=dis(),mx0=dis(),lmax1=0,rmax1=0,sum1=0,mx1=0;}	//操作0
	void change(){swap(lmax0,lmax1),swap(rmax0,rmax1),swap(mx1,mx0),swap(sum0,sum1);}	//操作2 :交换0和1的数据即可
};
node K[4*200000];
void push(int rt){	//向上更新操作
	int q=rt<<1;
	int p=q+1;
	K[rt].lmax1=K[q].lmax1; K[rt].rmax1=K[p].rmax1;
	K[rt].lmax0=K[q].lmax0;	K[rt].rmax0=K[p].rmax0;
	K[rt].sum0=K[q].sum0+K[p].sum0;
	K[rt].sum1=K[q].sum1+K[p].sum1;
	K[rt].mx1=max(max(K[q].mx1,K[p].mx1),K[q].rmax1+K[p].lmax1);		//这里以下是能够区间合并时需要更新的数据
	K[rt].mx0=max(max(K[q].mx0,K[p].mx0),K[q].rmax0+K[p].lmax0);
	if(K[q].lmax0==K[q].dis()) K[rt].lmax0=K[q].dis()+K[p].lmax0;	
	if(K[p].rmax0==K[p].dis()) K[rt].rmax0=K[p].dis()+K[q].rmax0;
	if(K[q].lmax1==K[q].dis()) K[rt].lmax1=K[q].dis()+K[p].lmax1;
	if(K[p].rmax1==K[p].dis()) K[rt].rmax1=K[p].dis()+K[q].rmax1;
	return ;		 
}
void build(int l,int r,int rt){
	K[rt].mode=0;
	K[rt].L=l;
	K[rt].R=r;
	if(l==r){
		if(data[l]==0){K[rt].set_0();}
		else{K[rt].set_1();}
		return;
	}
	int m=K[rt].mid();
	build(l,m,rt<<1);
	build(m+1,r,rt<<1|1);
	push(rt);
	return ;
}
void trans(int transmode,int rt){		//操作函数
	if(transmode==1){
		K[rt].set_0();
	}
	else if(transmode==2){
		K[rt].set_1();
	}
	else if(transmode==3){
		K[rt].change();
	}
	return;
}
void modechan(int son,int fa){
	if(K[fa].mode==3){
		K[son].mode=K[fa].mode-K[son].mode;//3-3=0,3-1=2,3-2=1 因此正好可以用一个减法。(或者可以用两个延迟标记来区分操作0,1与操作2)
	}
	else
		K[son].mode=K[fa].mode;
	return ;
}
void updata(int M,int L,int R,int rt){	//更新操作
	if(K[rt].L>=L&&K[rt].R<=R)
	{
			if(M==2&&K[rt].mode){			//这里表示在原来有延迟标记并且要赋予操作2的情况该如何转化
				trans(M+1,rt);		//先把该结点更新
				K[rt].mode=M/K[rt].mode;		
			}
			else{					//原来没有延迟标记或要赋予的不是操作2,直接覆盖。
				trans(M+1,rt);
				K[rt].mode=M+1;
			}
		return ;
	}
	if(K[rt].mode){
		trans(K[rt].mode,rt<<1);
		trans(K[rt].mode,rt<<1|1);
		modechan(rt<<1,rt);
		modechan(rt<<1|1,rt);
		K[rt].mode=0;
	}
	int m=K[rt].mid();
	if(R<=m)
		updata(M,L,R,rt<<1);
	else if(L>m)
		updata(M,L,R,rt<<1|1);
	else
	{
		updata(M,L,R,rt<<1);
		updata(M,L,R,rt<<1|1);
	}
	push(rt);
	return;
}

int query(int M,int L,int R,int rt){
	if(K[rt].L>=L&&K[rt].R<=R){
		if(M==3){
			return K[rt].sum1;
		}
		else
			return K[rt].mx1;
	}
	if(K[rt].mode){
		trans(K[rt].mode,rt<<1);
		trans(K[rt].mode,rt<<1|1);
		modechan(rt<<1,rt);
		modechan(rt<<1|1,rt);	
		K[rt].mode=0;
	}
	int m=K[rt].mid();
	if(R<=m)
		return query(M,L,R,rt<<1);
	else if(L>m)
		return query(M,L,R,rt<<1|1);
	else{
		int k1=query(M,L,R,rt<<1);
		int k2=query(M,L,R,rt<<1|1);
		if(M==4){
				int s=min(K[rt<<1].rmax1,m-L+1)+min(K[rt<<1|1].lmax1,R-m);
				return max(s,max(k1,k2));
		}
		else return k1+k2;
	}
}


int main(){
	int t,n,m;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
			scanf("%d",&data[i]);
		build(1,n,1);
		int G,L,R;
		for(int i=1;i<=m;i++){
			scanf("%d%d%d",&G,&L,&R);	//这里我定义的区间是[1,n] 所以在给的数据上要+1
			if(G==3||G==4)
				printf("%d\n",query(G,L+1,R+1,1));
			else
				updata(G,L+1,R+1,1);
		}
	}
}

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值