[线段树]校OJ-序列操作1

这是一篇关于使用线段树解决序列操作问题的博客,主要介绍了如何处理包含n个数的序列,并应对两种操作:单点修改和区间最大值查询。样例和数据范围给出,题目限制a, b <= 105, n <= 105。解决方案中提到,利用线段树模板,可以高效地完成m次区间查询和单点修改,线段树的大小设为4倍的n。" 94399942,8637201,Node.js环境搭建与模块化详解,"['Node.js', '模块化', '服务器开发', 'npm管理', 'JavaScript']

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

序列操作1

题目简述

给定一个包含n个数的序列,初值全为0,现对这个序列有两种操作:

操作1:把 给定 第k1 个数改为k2;

操作2:查询 从第k1个数到第k2个数的最大值。(k1<=k2<=n)

样例

//input
3 
1 2 2
1 3 3
2 2 3
//output
3

数据范围
a , b < = 1 0 5 a,b<=10^5 a,b<=105, n < = 1 0 5 n<=10^5 n<=105

思路

模板题,在一棵线段树中进行 m m m次区间查询 ( 注 意 本 题 中 m = n ) (注意本题中m=n) (m=n),单点修改操作,注意线段树范围要开到 4 ∗ n 4*n 4n即可。

code

#include <bits/stdc++.h>
using namespace std;
const int MAXN=100086;
struct tree
{
	int l,r,maxx;
}t[4*MAXN];//4*n!!!
int n,a[MAXN];
void build(int bh,int l,int r)
{
	t[bh].l=l;	
	t[bh].r=r;	
	if(l==r)
	{
		t[bh].maxx=a[l];//叶节点中的最大值为它本身,下同
		return ;
	}
	int mid=(l+r)/2;
	build(2*bh,l,mid);
	build(2*bh+1,mid+1,r);
	t[bh].maxx=max(t[bh*2].maxx,t[bh*2+1].maxx);//每次回溯完更新最大值,下同
}
void change(int bh,int x,int sum)
{
	if(t[bh].l==t[bh].r )
	{
		t[bh].maxx=sum;
		return;
	}
	int mid=(t[bh].l+t[bh].r )/2;
	if(x<=mid) change(bh*2,x,sum);
	else change(bh*2+1,x,sum);
	t[bh].maxx=max(t[bh*2].maxx,t[bh*2+1].maxx);
}
int ask(int bh,int l,int r)
{
	if(l<=t[bh].l&&r>=t[bh].r)
	{
		return t[bh].maxx;
	}
	int mid=(t[bh].l+t[bh].r)/2;
	int w=-MAXN*100;
	if(l<=mid) w=max(w,ask(bh*2,l,r));
	if(r>mid) w=max(w,ask(bh*2+1,l,r));
	return w;//查询区间最大值
}
int main()
{
	scanf("%d",&n);
	build(1,1,n);//第一个1表示从根节点1出发,下面的ask和change函数同理
	while(n--)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		if(a==1) change(1,b,c);
		else printf("%d\n",ask(1,b,c));	
	}
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值