HDU 1754 I Hate It

线段树操作与应用
本文介绍了线段树的基本概念,包括单点替换和区间最大值查询,并通过代码实例展示了如何实现这些操作。

线段树的单点替换、区间求最大


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 200004
#define MAX INT_MAX
#define MIN INT_MIN
struct node
{
	int left,right;
	int num; //
}T[4*N];
int ans=0;
void putup(int id)
{
    T[id].num = max(T[id*2].num,T[id*2+1].num);
}
void Creat(int left,int right,int id)//建树
{
	T[id].left =left;
	T[id].right =right;
	T[id].num =0;
	if(T[id].left ==T[id].right )
		return ;
	Creat(left,(left+right)/2,2*id);
	Creat((left+right)/2+1,right,2*id+1);
}
void UPdata(int id,int i,int j)//单点更新,即单点替换

{
	if(T[id].left<=i&&T[id].right >=i)
		T[id].num = j;
	if(T[id].left ==T[id].right )
		return;
	if(i>T[id].right )
		return;
	if(i<T[id].left )
		return;
	int mid=(T[id].left +T[id].right )/2;
	if(i<=mid)
		UPdata(id*2,i,j);
	else
		UPdata(id*2+1,i,j);

}
void query(int id,int l,int r)//区间&&单点查询,l-r 区间内的所有人
{
	int mid=(T[id].left +T[id].right)/2;
	if(T[id].left ==l&&T[id].right ==r)
	{
		if(T[id].num >ans)
            ans = T[id].num;
		return;
	}
	if(r<=mid)
		query(2*id,l,r);
	else if(l>mid)
		query(2*id+1,l,r);
	else
	{
		query(2*id,l,mid);
		query(2*id+1,mid+1,r);
	}

}

int main()
{
    int n,m,x,l,r;
    char str[5];
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        Creat(1,n,1);
        for(int i = 1;i<=n;i++)
        {
            scanf("%d",&x);
            UPdata(1,i,x);
        }
        for(int i = 1;i<=m;i++)
        {
            scanf("%s",str);
            if(str[0]=='Q')
            {
                scanf("%d%d",&l,&r);
                ans = -9999999;
               query(1,l,r);
                printf("%d\n",ans);
                ans = -9999999;
            }
            else if(str[0]=='U')
            {
                scanf("%d%d",&l,&r);
                UPdata(1,l,r);
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值