[线段树]校OJ-序列操作1
Posted zero_orez6
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[线段树]校OJ-序列操作1相关的知识,希望对你有一定的参考价值。
序列操作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 4∗n即可。
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;
}
以上是关于[线段树]校OJ-序列操作1的主要内容,如果未能解决你的问题,请参考以下文章