最敏捷的机器人 LibreOJ 10120 RMQ问题分别做一个最大值与最小值

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

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

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

Input

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

第二行共 nn 个数,为数字序列,所有数字均在 Pascal 的 longint 范围内,即所有数均为整数,且在 [231,2311][−231,231−1] 范围内。

Output

共 nk+1n−k+1 行,第 ii 行为第 ii 至第 i+k1i+k−1 这 kk 个数中的最大和最小值。

Example

样例输入

5 3
1 2 3 4 5

样例输出

3 1
4 2
5 3

Hint

对于全部数据,1kn1051≤k≤n≤105。

#include <bits/stdc++.h>
using namespace std;
inline ll read(){
    char ch=getchar();ll res=0,f=1;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar();
    return res*f;
}
inline void write(ll zx){
    if(zx<0) zx=-zx,putchar('-');
    if(zx<10) putchar(zx+'0');
    else{
        write(zx/10);
        putchar(zx%10+'0');
    }
}
ll n,m,a[100010],f[100010][20],f2[100010][20];
void ST(){
    for(ll i=1;i<=n;i++) f[i][0]=a[i];
    for(ll j=1;(1<<j)<=n;j++) {
        for(ll i=1;i+(1<<j)-1<=n;i++) {
            f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
        }
    }
}
ll RMQ(ll l,ll r){
    ll k=0;
    while((1<<(k+1))<=r-l+1) k++;
    return max(f[l][k],f[r-(1<<k)+1][k]);
}
void ST2(){
    for(ll i=1;i<=n;i++) f2[i][0]=a[i];
    for(ll j=1;(1<<j)<=n;j++) {
        for(ll i=1;i+(1<<j)-1<=n;i++) {
            f2[i][j]=min(f2[i][j-1],f2[i+(1<<(j-1))][j-1]);
        }
    }
}
ll RMQ2(ll l,ll r){
    ll k=0;
    while((1<<(k+1))<=r-l+1) k++;
    return min(f2[l][k],f2[r-(1<<k)+1][k]);
}
int main(){
    n=read();m=read();
    for(ll i=1;i<=n;i++) a[i]=read();
    ST();ST2();
    for(ll i=1;i<=n-m+1;i++){
        write(RMQ(i,i+m-1));
        putchar(' ');
        write(RMQ2(i,i+m-1));
        putchar('\n');
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xxxsans/p/12747698.html