区间最大值 II
Time Limit: 1000 MS Memory Limit: 65535 K
Description
给一个有n个整数的序列a1, a2, a3, …, an,然后有q个提问,每个提问为两个整数i、j,(i<=j),请你回答,在ai到aj中,最大值是多少。
注意:1 <= n,q <= 100000, ai在int整型表示的范围内。
Input
有多组测试数据。
每组测试数据的第一行为一个整数n,表示有n个数;
第二行为n个整数,表示a1,a2,..an;
第三行为q,表示q个提问。
接下来有q行,每行两个数i, j, (i <= j)。
Output
每组测试数据先输出一行”Case n:”, n从1开始计数;
接下来有q行,每行对应一个提问,每行只有一个整数,为ai到aj间的最大值。
Sample Input
3
1 3 2
2
1 2
2 3
4
1 2 3 4
3
1 2
2 4
1 1
Sample Output
Case 1:
3
3
Case 2:
2
4
1
Hint
题目数据已更新。
题意
RT
思路
数据量巨大,很明显暴力不可取。
用RMQ对数据进行高效维护即可w
PS:线段树维护也可以,不过感觉代码量会更多一些w
坑点
cin,cout进行数据的操作会超时。
AC代码
#include<bits/stdc++.h>
using namespace std;
int A[100006];
int dp[100006][32];
/*RMQ一般操作*/
void ST(int n)
{
for(int i = 1 ; i <= n ; i++) dp[i][0] = A[i];
for(int j = 1 ; (1 << j) <= n ; j++)
{
for(int i = 1 ; i + (1 << j) - 1 <= n ; i++)
{
dp[i][j] = max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
}
int RMQ(int l,int r)
{
int k = log2(r - l + 1);
return max(dp[l][k],dp[r - (1<<k) + 1][k]);
}
void solve(void)
{
int n;
int flag = 1;
while(~scanf("%d",&n))///注意输入输出不要用cin,cout
{
for(int i = 1 ; i <= n ; i++) cin >> A[i];
ST(n);
int q;
scanf("%d",&q);
printf("Case %d:\n",flag);
flag++;
for(int i = 0 ; i < q ; i++)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",RMQ(l,r));
}
}
}
int main(void)
{
solve();
return 0;
}