【数据结构】线段树实现ST表功能(RMQ问题)

POJ3264为例引入吧。其实还是很基础的线段树一种。这里不用修改,只要建树+查询即可了。但是我一开始用C++的输入输出流配套IO就tle了,换成C的scanf输入就ac了,还是挺卡时间的吧。但处理区间RMQ问题还是推荐ST表,因为ST表每次查询就O(1),但线段树的话,每次查询的话就是一个search过程,是O(logn)的复杂度,相比ST表劣势就出来了。不过这题数据范围给的小,线段树也能过。换成大一点的可能就TLE了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;

ll input[500010];

struct node{
	ll l,r,sum,lz,maxx,minn;
}tree[2000040];

int ans,n,m;

inline void build(ll i,ll l,ll r){
	tree[i].l=l;tree[i].r=r,tree[i].lz=0;
	if(l==r){
		tree[i].sum=tree[i].maxx=tree[i].minn=input[l];
		return ;
	}
	ll mid=(l+r)>>1;
	build(2*i,l,mid);
	build(2*i+1,mid+1,r);
	tree[i].sum=tree[2*i].sum+tree[i*2+1].sum;
	tree[i].maxx=max(tree[2*i].maxx,tree[2*i+1].maxx);
	tree[i].minn=min(tree[2*i].minn,tree[2*i+1].minn);
}


inline ll searchmax(ll i,ll l,ll r){
    if(tree[i].l>=l && tree[i].r<=r) //查max
        return tree[i].maxx;
    if(tree[i].r<l || tree[i].l>r)  return 0;
    ll s=0;
    if(tree[i*2].r>=l)  s=max(s,searchmax(i*2,l,r));
    if(tree[i*2+1].l<=r)  s=max(s,searchmax(i*2+1,l,r));
    return s;
}

inline ll searchmin(ll i,ll l,ll r){
    if(tree[i].l>=l && tree[i].r<=r) //查min
        return tree[i].minn;
    if(tree[i].r<l || tree[i].l>r)  return 0;
    ll s=INF;
    if(tree[i*2].r>=l)  s=min(s,searchmin(i*2,l,r));
    if(tree[i*2+1].l<=r)  s=min(s,searchmin(i*2+1,l,r));
    return s;
}


int main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&input[i]);
	build(1,1,n);
	while(m--){
		ll l,r;
		scanf("%lld%lld",&l,&r);
		printf("%lld\n",searchmax(1,l,r)-searchmin(1,l,r));
	}
}

发布了71 篇原创文章 · 获赞 5 · 访问量 3392

猜你喜欢

转载自blog.csdn.net/Rainfoo/article/details/104029851
今日推荐