AcWing 1270. 数列区间最大值(RMQ问题)

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 1270. 数列区间最大值(RMQ问题)相关的知识,希望对你有一定的参考价值。

题目链接

https://www.acwing.com/problem/content/description/1272/

思路

我们这次需要维护一下区间的最大值,也就是经典的 RMQ 问题,由于没有更新操作,所以只写了 buildquery 部分,原理都非常简单,相当于是模板了 ,详情请看代码

代码

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

#define endl "\\n"
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3f

const int N = 2e5+10;

ll a[N];

struct Tnode
	ll l,r,sum,lazy,Max;
;

struct SegmentTree
	
	Tnode tree[N<<2];
	
	inline void push_up(ll root)//向上更新
		tree[root].Max = max(tree[root<<1].Max , tree[(root<<1) | 1].Max);
	
	
	void build(ll l,ll r,ll root)//建树
		tree[root].l = l;
		tree[root].r = r;
		if(l == r) tree[root].Max = a[l];
		else
			ll mid = ((r+l) >> 1);
			build(l,mid,root<<1);
			build(mid+1,r,(root<<1)+1);
			push_up(root);
		
	
	ll query(ll l,ll r,ll root) //区间查询
		if(tree[root].l >= l && tree[root].r <= r) return tree[root].Max;
		else
			ll mid = tree[root].l + ((tree[root].r-tree[root].l) >> 1);
			ll ans = -INF;
			if(l <= mid) ans = max(ans,query(l,r,root<<1));//如果我们查询区间的左边界比当前节点的中间点小,那么说明查询区间要往左走
			if(r > mid)  ans = max(ans,query(l,r,(root<<1) + 1));//如果我们查询的右边界要比当前节点的中间节点大,那么说明查询区间要往右走
			return ans;
		
	
Tree;

int n,m;

int main()

	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(int i = 1;i <= n; ++i) cin>>a[i];
	Tree.build(1,n,1);
	ll l,r;
	for(int t = 1;t <= m; ++t)
		cin>>l>>r;
		cout<<Tree.query(l,r,1)<<endl;
	

/*

Testcase:
input

10 2
3 2 4 5 6 8 1 2 9 7
1 4
3 8

output:

5
8
 */

以上是关于AcWing 1270. 数列区间最大值(RMQ问题)的主要内容,如果未能解决你的问题,请参考以下文章

第五讲 树状数组与线段树 未完结

HDU - 5289 Assignment (RMQ+二分)

RMQ(区间最值问题)

51NOD1174 区间最大数 && RMQ问题(ST算法)

ST算法(RMQ区间最值问题)

ST算法(RMQ区间最值问题)