洛谷P3865 【模板】ST表 #ST表#

题目背景

这是一道ST表经典题——静态区间最大值

请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1)O(1)

题目描述

给定一个长度为 NN 的数列,和 MM 次询问,求出每一次询问的区间内数字的最大值。

输入格式

第一行包含两个整数 N,MN,M ,分别表示数列的长度和询问的个数。

第二行包含 NN 个整数(记为 aiai​),依次表示数列的第 ii 项。

接下来 MM行,每行包含两个整数 li,rili​,ri​,表示查询的区间为 [li,ri][li​,ri​]

输出格式

输出包含 MM行,每行一个整数,依次表示每一次询问的结果。

输入输出样例

输入 #1复制

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

输出 #1复制

9
9
7
7
9
8
7
9

说明/提示

对于30%的数据,满足: 1≤N,M≤101≤N,M≤10

对于70%的数据,满足: 1≤N,M≤1051≤N,M≤105

对于100%的数据,满足: 1≤N≤105,1≤M≤106,ai∈[0,109],1≤li≤ri≤N1≤N≤105,1≤M≤106,ai​∈[0,109],1≤li​≤ri​≤N

题解

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 1e5 + 10;
const int logn = 20;
int Log[maxn], f[maxn][logn];

inline const int read()
{
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

void init()
{
    Log[1] = 0; Log[2] = 1;
    for (int i = 3; i < maxn; i++) Log[i] = Log[i / 2] + 1;
}

int main()
{
    int n = read(), m = read();
    for (int i = 1; i <= n; i++) f[i][0] = read();
    init();
    for (int j = 1; j <= logn; j++)
        for (int i = 1; i + (1 << j) - 1 <= n; i++)
            f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
    while (m--)
    {
        int l = read(), r = read();
        int s = Log[r - l + 1];
        printf("%d\n", max(f[l][s], f[r - (1 << s) + 1][s]));
    }
    return 0;
}
发布了367 篇原创文章 · 获赞 148 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_35850147/article/details/103282961
今日推荐