Balanced Lineup(线段树同时维护最大最小)

题目传送门

题意:给定一群奶牛的身高,给定m次询问,对于每次询问,输出这个询问区间内,身高的最大值和最小值之差。

思路
和单维护最大值差不多,多维护一个最小值即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e4+5;
const int mod=1e9+7;
const int INF=0x7fffffff;
const ll LLINF=0x7fffffffffffffff;
const double EPS=1e-10;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define debug cout<<"debug"<<endl;
#define ls p<<1
#define rs p<<1|1
//#define int long long
int a[N];
struct tree
{
    int l,r,ma,mi;
}t[N<<2];
void build(int p,int x,int y)
{
    t[p].l=x;t[p].r=y;
    if(x==y)
    {
        t[p].ma=a[x];t[p].mi=a[x];
        return ;
    }
    int mid=x+y>>1;
    build(ls,x,mid);
    build(rs,mid+1,y);
    t[p].ma=max(t[ls].ma,t[rs].ma);
    t[p].mi=min(t[ls].mi,t[rs].mi);
}
int ask1(int p,int x,int y)
{
    int ans=0;
    if(x<=t[p].l&&t[p].r<=y)
    {
        return t[p].ma;
    }
    int mid=t[p].l+t[p].r>>1;
    if(x<=mid)
    {
        ans=max(ans,ask1(ls,x,y));
    }
    if(y>mid)
    {
        ans=max(ans,ask1(rs,x,y));
    }
    return ans;
}
int ask2(int p,int x,int y)
{
    int ans=INF;
    if(x<=t[p].l&&t[p].r<=y)
    {
        return t[p].mi;
    }
    int mid=t[p].l+t[p].r>>1;
    if(x<=mid)
    {
        ans=min(ans,ask2(ls,x,y));
    }
    if(y>mid)
    {
        ans=min(ans,ask2(rs,x,y));
    }
    return ans;
}
signed main()
{
    IOS;
    //freopen("","r",stdin);
    //freopen("","w",stdout);
    int n,q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",a+i);
    }
    build(1,1,n);
    while(q--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d\n",ask1(1,a,b)-ask2(1,a,b));
    }
}
发布了93 篇原创文章 · 获赞 9 · 访问量 4204

猜你喜欢

转载自blog.csdn.net/Joker_He/article/details/104433108
今日推荐