51nod 1174 区间中最大的数(RMQ)

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
收藏
关注
取消关注
给出一个有N个数的序列,编号0 - N - 1。进行Q次查询,查询编号i至j的所有数中,最大的数是多少。
 
例如: 1 7 6 3 1。i = 1, j = 3,对应的数为7 6 3,最大的数为7。(该问题也被称为RMQ问题)
Input
第1行:1个数N,表示序列的长度。(2 <= N <= 10000)
第2 - N + 1行:每行1个数,对应序列中的元素。(0 <= S[i] <= 10^9)
第N + 2行:1个数Q,表示查询的数量。(2 <= Q <= 10000)
第N + 3 - N + Q + 2行:每行2个数,对应查询的起始编号i和结束编号j。(0 <= i <= j <= N - 1)
Output
共Q行,对应每一个查询区间的最大值。
Input示例
5
1
7
6
3
1
3 0 1 1 3 3 4
Output示例
7
7
3

RMQ问题的ST解法
 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 int dp[10005][40];
 5 int a[10005];
 6 int n;
 7 void init_RMQ()
 8 {
 9     for(int i=0;i<n;i++)
10         dp[i][0]=a[i];
11     for(int j=1;(1<<j)<=n;j++)
12     {
13         for(int i=0;i+(1<<(j-1))<=n;i++)
14         {
15             dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
16         }
17     }
18 }
19 int query(int l,int r)
20 {
21     int k=0;
22     while((1<<k)<=(r-l+1))
23         k++;
24     k--;
25     return max(dp[l][k],dp[r-(1<<k)+1][k]);
26 }
27 int main()
28 {
29     cin>>n;
30     for(int i=0;i<n;i++)
31         cin>>a[i];
32     int q;
33     cin>>q;
34     init_RMQ();
35     while(q--)
36     {
37         int l,r;
38         cin>>l>>r;
39         cout<<query(l,r)<<endl;
40     }
41     return 0;
42 }
View Code

设dp[i][j]表示以i为起点,区间长度为2^j的范围最大值。

初始化dp[i][0]=a[i];然后枚举区间范围j更新dp[i][j].

对于查询操作,【l,r】最大值=max(dp[l][k],dp[r-(1<<k)+1][k]),其中k为小于查询区间长度的最大j值。



原文地址:https://www.cnblogs.com/onlyli/p/7241921.html