题目链接: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));

     }

 }