번호 시퀀스 간격 최대 값 | 선분 트리

시퀀스 간격의 최대 값


acwing 1270
제한 시간 : 2 초
메모리 제한 : 64MB

문제 설명

숫자 문자열을 입력하고 M 개의 쿼리를 제공합니다. 각 쿼리는 두 개의 숫자 X를 제공하고 Y는 X에서 Y까지의 간격에서 최대 수를 말하도록 요청합니다.

입력

  • 첫 번째 줄에있는 두 개의 정수 N과 M은 자릿수와 쿼리 수를 나타냅니다.

    다음 행은 N 개의 숫자입니다.

    다음 M 행, 각 행에는 두 개의 정수 X, Y가 있습니다.

    1≤N≤10는 5
    1≤M≤10 6
    1≤X≤Y≤N 없음
    시퀀스의 수는 2 초과 31 -1

산출

총 M 라인의 출력이 있으며 각 라인은 숫자를 출력합니다.

샘플 입력

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

샘플 출력

5
8

선분 트리 솔루션

AC 코드 :
#include<cstdio>
#include<iostream>
using namespace std;
int n,m,x[100005];          //原数组
struct Node{
    
    
    int l,r,w;              //线段树的左、右、值
};
Node tree[400005];          //线段树
void build(int num,int l,int r){
    
    
    if(l == r){
    
                 //相等说明已经到了叶子节点
        tree[num].l = l,tree[num].r = r,tree[num].w = x[l];return;
    }
    int mid = (l + r) >> 1;
    int lc = num << 1;      //乘2是左子树
    int rc = num << 1 | 1;  //乘2或1是右子树
    build(lc,l,mid);        //建左子树
    build(rc,mid + 1,r);  //建右子树
    tree[num].l = l,tree[num].r = r,tree[num].w = max(tree[lc].w,tree[rc].w);return;    //保存左右子树的最大子(区间最大)
}
int find(int num,int l,int r){
    
    
    if(tree[num].l == l && tree[num].r == r)
        return tree[num].w;             //找到目标区间
    int mid = (tree[num].l + tree[num].r) >> 1;
    int lc = num << 1;
    int rc = num << 1 | 1;
    if(l > mid)
        return find(rc,l,r);    //继续在右子树找
    else if(r <= mid)
        return find(lc,l,r);    //继续在左子树找
    else return max(find(lc,l,mid),find(rc,mid + 1,r)); //左子树找一段,右子树找一段
}
int main(){
    
    
    scanf("%d %d",&n,&m);
    for(int i = 1;i <= n;++i)
        scanf("%d",x + i);
    build(1,1,n);
    while(m--){
    
    
        int l,r;
        scanf("%d %d",&l,&r);
        printf("%d\n",find(1,l,r));
    }
    return 0;
}

추천

출처blog.csdn.net/qq_45985728/article/details/113727439