「一本通 4.2 例 2」最敏捷的机器人(loj10120)

题目描述

Wind 设计了很多机器人。但是它们都认为自己是最强的,于是,一场比赛开始了……

机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛。首先,他们面前会有一排共 n 个数,它们比赛看谁能最先把每连续 k 个数中最大和最小值写下来,当然,这些机器人运算速度都很快,它们比赛的是谁写得快。

但是 Wind 也想知道答案,你能帮助他吗?

输入格式

第一行为 n,k,意义如题目描述。

第二行共 n 个数,为数字序列,所有数字均在 Pascallongint 范围内,即所有数均为整数,且在 [−2^31,2^31−1]之间31​​,231​​1] 范围内。

输出格式

n−k+1行,第 i 行为第 i至第 i+k−1k 个数中的最大和最小值。

样例

样例输入

5 3
1 2 3 4 5

样例输出

3 1
4 2
5 3

数据范围与提示

对于全部数据,1≤k≤n≤10^5, 第 i 行为第 i 至第 i+k−1k 个数中的最大和最小值。

#include<cstdio>
#include<iostream>
#define RI register int
using namespace std;
const int maxn = 1000010;
int llog[maxn];
int f[maxn][20];
int g[maxn][20];
int n, k;
inline void qread(int &x) {
    x = 0;
    register int ch = getchar(), flag = 0;
    while(ch < '0' || ch > '9') {
        if(ch == '-')
            flag = 1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = 10 * x + ch - 48;
        ch = getchar();
    }
    if(flag)    x = -x;
}
int main(void) {
    qread(n);
    qread(k);
    for(RI i = 2; i <= n; ++i)
        llog[i] = llog[i >> 1] + 1;
    for(RI i = 1; i <= n; ++i)
        qread(f[i][0]);
    for(RI i = 1; i <= n; ++i)
        g[i][0] = f[i][0];
    for(int i = 1; i <= llog[k]; ++i)
        for(int j = 1; j <= n; ++j) {
            f[j][i] = max(f[j][i - 1], f[j + (1 << (i - 1))][i - 1]);
            g[j][i] = min(g[j][i - 1], g[j + (1 << (i - 1))][i - 1]);
        }
    for(int i = 1; (i + k - 1) <= n; ++i) {
        printf("%d ", max(f[i][llog[k]], f[i + k - (1 << llog[k])][llog[k]]));
        printf("%d\n",  min(g[i][llog[k]], g[i + k - (1 << llog[k])][llog[k]]));
    }
}

思路:

  ST表,注意数组要开大些,否则可能爆内存

5​​。

猜你喜欢

转载自www.cnblogs.com/junk-yao-blog/p/9472294.html