【线段树】poj 3264 Balanced Lineup(外:hdu 1754 I Hate It)

本文详细介绍了两种区间查找与更新算法的实现方法,包括如何使用线段树结构进行区间最大值和最小值的查找与更新操作。通过实例分析,阐述了算法的核心思想和具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://poj.org/problem?id=3264

题意:求某区间内最大值和最小值的差值

分析:区间查找最值

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int NM=50005;

struct Tree{
	int mmin,mmax;
}T[NM*4];

void Build(int lf,int rg,int root)
{
	if(lf==rg){
		scanf("%d",&T[root].mmax);
		T[root].mmin=T[root].mmax;
		return;
	}
	int mid=(lf+rg)>>1;
	Build(lf,mid,root<<1);
	Build(mid+1,rg,root<<1|1);
	T[root].mmax=T[root<<1].mmax>T[root<<1|1].mmax?T[root<<1].mmax:T[root<<1|1].mmax;
	T[root].mmin=T[root<<1].mmin<T[root<<1|1].mmin?T[root<<1].mmin:T[root<<1|1].mmin;
}

int Find(int x,int y,int lf,int rg,int root,bool f)
{
	if(lf==x&&rg==y) 
	{
		if(f) return T[root].mmax;
		else return T[root].mmin;
	}
	
	int mid=(lf+rg)>>1;
	if(y<=mid) 
		return Find(x,y,lf,mid,root<<1,f);
	else if(x>mid) 
		return Find(x,y,mid+1,rg,root<<1|1,f);
	else{
		int t1=Find(x,mid,lf,mid,root<<1,f);
		int t2=Find(mid+1,y,mid+1,rg,root<<1|1,f);
		
		if(f) return t1>t2?t1:t2;
		else return t1<t2?t1:t2;
	}
}

int main()
{
	int i,n,m,x,y,t1,t2;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		Build(1,n,1);
		for(i=0;i<m;i++)
		{
			scanf("%d%d",&x,&y);
			t1=Find(x,y,1,n,1,true);
			t2=Find(x,y,1,n,1,false);
			printf("%d\n",t1-t2);
		}
	}
	return 0;
}

http://acm.hdu.edu.cn/showproblem.php?pid=1754

分析:单点更新,区间查找最值

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int NM=200005;
int T[NM*4];

inline int max(int x,int y){
	return x>y?x:y;
}

void Build(int lf,int rg,int rt)
{
	if(lf==rg){
		scanf("%d",&T[rt]);
		return;
	}
	int mid=(lf+rg)>>1;
	Build(lf,mid,rt<<1);
	Build(mid+1,rg,rt<<1|1);
	T[rt]=max(T[rt<<1],T[rt<<1|1]);
}

void Update(int id,int data,int lf,int rg,int rt)
{
	if(lf==rg){
		T[rt]=data;
		return;
	}
	int mid=(lf+rg)>>1;
	if(id<=mid) Update(id,data,lf,mid,rt<<1);
	else Update(id,data,mid+1,rg,rt<<1|1);
	T[rt]=max(T[rt<<1],T[rt<<1|1]);
}

int FindMax(int x,int y,int lf,int rg,int rt)
{
	if(lf==x&&y==rg) return T[rt];
	int mid=(lf+rg)>>1;
	if(x>mid) 
		return FindMax(x,y,mid+1,rg,rt<<1|1);
	else if(y<=mid) 
		return FindMax(x,y,lf,mid,rt<<1);
	else {
		int t1=FindMax(x,mid,lf,mid,rt<<1);
		int t2=FindMax(mid+1,y,mid+1,rg,rt<<1|1);
		return max(t1,t2);
	}
}

int main()
{
	int n,m,i,x,y;
	char str[3];
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		Build(1,n,1);
		for(i=0;i<m;i++)
		{
			scanf("%s%d%d",str,&x,&y);
			if(str[0]=='U') Update(x,y,1,n,1);
			else {
				printf("%d\n",FindMax(x,y,1,n,1));
			}
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值