hduProblem-1754线段树的应用

本文介绍了一种基于线段树的数据结构实现方法,并详细解释了如何通过递归构建、更新及查询线段树来解决特定问题。文章通过一个具体的例子展示了如何初始化线段树、进行单点更新以及区间查询等操作。
#include <bits/stdc++.h>
//#define N 200005
//#define M 599999	
const int N=200005;    	//const比define快, 
const int M=599999;
using namespace std;

struct node
{
	int left,right;
	int value;	
}st[M];			//注意st[]和father[]这两个数组空间大概3倍(强调不是两倍)
int father[N];
int MAX;

void buildTree(int i,int left,int right)	//递归,建树 
{
	st[i].left=left;
	st[i].right=right;
	st[i].value=0;
	if(left==right)
	{
		father[left]=i;
		return ;
	}
	buildTree(i<<1,left,(left+right)/2);		//位操作比直接乘法i*2快 
	buildTree((i<<1)+1,(left+right)/2+1,right);
}
void updateTree(int ri)		//递归,单点更新,更新ri结点的父结点 
{
	if(ri==1)
		return ;
	int fi=ri/2;
	int a=st[fi<<1].value;
	int b=st[(fi<<1)+1].value;
	st[fi].value=(a>b)?a:b;
	updateTree(fi);
}
void query(int i,int l,int r)	//递归查询 ,在结点i查询[l,r] 
{
	if(l==st[i].left&&r==st[i].right)
	{
		MAX=(st[i].value>MAX)?st[i].value:MAX;
		return ; 
	}
	i=i<<1;
	if(l<=st[i].right)
	{
		if(r<=st[i].right)
			query(i,l,r);
		else	
			query(i,l,st[i].right);
	}
	i=i+1;
	if(r>=st[i].left)
	{
		if(l>=st[i].left)
			query(i,l,r);
		else
			query(i,st[i].left,r);	
	}
}
int main()
{
	int n,m;
	while(scanf("%d %d",&n,&m)!=EOF)	//本题目包含多组测试,请处理到文件结束。
	{
		buildTree(1,1,n);
		int id=1,score;
		while(n--)	//输入n个学生的成绩 
		{
			scanf("%d",&score);
			st[father[id]].value=score;	//底层的无条件更新成绩  
			updateTree(father[id]);		//每一次都要更新线段树
			id++; 
		}
		char c[3];
		int a,b;
		while(m--)	//m次查询 
		{
//			 scanf("%c",&c);	//这样会读入回车,造成影响 
		   	 scanf("%s",c);	
			 if(c[0]=='Q')
			 {
			 	scanf("%d %d",&a,&b);
			 	query(1,a,b);
			 	cout<<MAX<<endl;
			 	MAX=-1<<20;		//重新赋值为很小的初始值 
			 }
			 else
			 {
			 	scanf("%d %d",&a,&b);
			 	st[father[a]].value=b;
			 	updateTree(father[a]);
			 }
		}
	}
	return 0;
} 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值