线段树模版

​
//题目大意:第一行给出N,Q两个数,(1<=N<=50000;1<=Q<=200000)接下来n行每一行有一个数,
//再接下来有Q组查询,每行查询给出一个区间[l,r](1<=l<=r<=N),输出该区间内最大值和最小值的差值。
//输入
//6 3
//1
//7
//3
//4
//2
//5
//1 5
//4 6
//2 2
//输出
//6
//3
//0

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

const int INF=0x3f3f3f3f;
const int N=50005;
int n,q;
struct node{
    int maxn,minn;
    node(){//初始化赋值
        maxn=0;
        minn=0;
    }
}tree[N<<2];//线段树一般都是4N大小,博客有很多大佬证明

void build(int k,int l,int r)//建树,k当前结点,l左边界,r右边界
{
    if(l==r)
    {
        int a;
        scanf("%d",&a);//a为给定的初值
        tree[k].maxn=a;
        tree[k].minn=a;
        return ;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);//向左建树
    build(k<<1|1,mid+1,r);//向右建树
    tree[k].maxn=max(tree[k<<1].maxn,tree[k<<1|1].maxn);//更新最大最小值
    tree[k].minn=min(tree[k<<1].minn,tree[k<<1|1].minn);
}

int ma=0;//当前区间的最大值
int mi=INF;//当前区间的最小值

void query(int L,int R,int l,int r,int k)
{
    if(L<=l&&r<=R)
    {
        if(tree[k].maxn>ma)
            ma=tree[k].maxn;
        if(tree[k].minn<mi)
            mi=tree[k].minn;
        return ;
    }
    int mid=(l+r)>>1;
    if(L<=mid)
        query(L,R,l,mid,k<<1);
    if(R>mid)
        query(L,R,mid+1,r,k<<1|1);
}

int main()
{
    scanf("%d%d",&n,&q);
    
    build(1,1,n);
    
    while(q--)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        ma=0;
        mi=INF;
        query(l,r,1,n,1);//查询[l,r]区间,更新最大最小值
        printf("%d\n",ma-mi);
    }
    return 0;
}

​

​

如有错误,欢迎指出!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值