The Water Problem
Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1634 Accepted Submission(s): 1245
Total Submission(s): 1634 Accepted Submission(s): 1245
In Land waterless, water is a very limited resource. People always fight for the biggest source of water. Given a sequence of water sources with
a1,a2,a3,...,an
representing the size of the water source. Given a set of queries each containing
2
integers
l
and
r
, please find out the biggest water source between
al
and
ar
.
Input
First you are given an integer
T(T≤10)
indicating the number of test cases. For each test case, there is a number
n(0≤n≤1000)
on a line representing the number of water sources.
n
integers follow, respectively
a1,a2,a3,...,an
, and each integer is in
{1,...,106}
. On the next line, there is a number
q(0≤q≤1000)
representing the number of queries. After that, there will be
q
lines with two integers
l
and
r(1≤l≤r≤n)
indicating the range of which you should find out the biggest water source.
Output
For each query, output an integer representing the size of the biggest water source.
Sample Input
3
1
100
1
1 1
5
1 2 3 4 5
5
1 2
1 3
2 4
3 4
3 5
3
1 999999 1
4
1 1
1 2
2 3
3 3
1
100
1
1 1
5
1 2 3 4 5
5
1 2
1 3
2 4
3 4
3 5
3
1 999999 1
4
1 1
1 2
2 3
3 3
Sample Output
100
2
3
4
4
5
1
999999
999999
1
2
3
4
4
5
1
999999
999999
1
题源:2015亚洲赛区长春网络赛
题目分析:区间求最大值。RMQ,模板题。
AC代码:
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#define maxn 10005
using namespace std;
int maxSum[maxn][20];
void RMQ(int num) //预处理->O(nlogn)
{
for(int j = 1;j < 20;j++)
{
for(int i = 1;i <= num;i++)
{
if((i + (1 << j) - 1) <= num)//区间长度要满足总数条件
{
maxSum[i][j] = max(maxSum[i][j - 1],maxSum[i + (1 << (j - 1))][j - 1]);
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int num,query;
int src,des;
scanf("%d",&num);
for(int i = 1;i <= num;i++)
{
scanf("%d",&maxSum[i][0]);//表示从第i个数起连续2^0(1)个数,即就是这第i个数
}
RMQ(num);
scanf("%d",&query);
while(query--)//O(1)查询
{
scanf("%d %d",&src,&des);
int k = (int)(log(des - src + 1.0) / log(2.0));//中间位置
int ansMax = max(maxSum[src][k],maxSum[des - (1 << k) + 1][k]);
printf("%d\n",ansMax);
}
}
return 0;
}