题目链接:http://acm.ocrosoft.com/problem.php?cid=1689&pid=3
题目描述:Wind设计了很多机器人。但是它们都认为自己是最强的,于是,一场比赛开始了~
机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛。 首先,它们面前会有一排共n个数,它们比赛看谁能最先把每连续k个数中最大和最小值写下来,当然,这些机器人运算速度都很快,它们比赛的是谁写的更快。
但是Wind也想知道答案,你能帮助他吗?
输入:
第一行为n,k两个数,(1<=k<=n<=100 000)。
第二行共n个数,为数字序列,所有数字均在longint范围内。
输出
共 n-k+1 行。
第 i 行为第 i~i+k-1 这 k 个数中的最大和最小值。
样例输入:
5 3
1 2 3 4 5
样例输出:
3 1
4 2
5 3
题目类型:
RMQ
思路:
这道题是一道RMQ模板题,当然和前面不同的是它要求的是最大值和最小值,因此我们要建立两个RMQ预处理内容,分别处理最大值和最小值
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int dp[N][25];
int dpm[N][25];
int a[N];
int n,m,x,y;
void RMQ_build()//预处理
{
for(int i=1;i<=n;i++)
{
dpm[i][0]=a[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]);//找最大值
dpm[i][j]=min(dpm[i][j-1],dpm[i+(1<<j-1)][j-1]);//找最小值
}
}
return;
}
int RMQ_query(int l,int r)//建立两个查询
{
int k=log2(r-l+1);
return max(dp[l][k],dp[r-(1<<k)+1][k]); //查询最大值
}
int RMQ_querym(int l,int r)
{
int k=log2(r-l+1);
return min(dpm[l][k],dpm[r-(1<<k)+1][k]); //查询最小值
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
RMQ_build();
for(int i=1;i<=n-m+1;i++)
{
printf("%d %d\n",RMQ_query(i,i+m-1),RMQ_querym(i,i+m-1));
}
}