其他分享
首页 > 其他分享> > 洛谷P1886 滑动窗口

洛谷P1886 滑动窗口

作者:互联网

典型的RMQ问题, 无需过多的解释。

一开始想用刚学的线段树, 于是费了九牛二虎之力打了个线段树,结果

具体为毛WA, 求大佬们指点。

然后我只好默默打了个ST表。

ST表这东西嘛, 真不错,简单粗暴,比线段树好调多了,然后就

就在这时, 我突然意识到其实不用开两个数组, 重复利用一个没准也可以水过去。 结果数据真的让我水过去了。

Code

#include <iostream>
#include <cstdio>
using namespace std;
//Benjamin
//(ST表)100分 
#define maxn 1000010
int log[maxn], f[1000001][20], a[maxn];
//空间所迫,这里不允许我们开两个fmax[][]和fmin[][]同时做,所以用牺牲时间的方式换取空间
int n, k, x, y;
int main() {
    scanf("%d%d", &n, &k);
    //接下来的步骤就基本上是ST表的模板了。
    log[0] = -1;
    for(int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        log[i] = log[i>>1] + 1;
        f[i][0] = a[i];
    }
    for(int j = 1; j <= 20; j++) {
        for(int i = 1; i + (1<<j) -1 <= n; i++) {
            f[i][j] = min(f[i][j-1], f[i + (1<<j-1)][j-1]);
        }
    }
    int m = n - k + 1;
    for(int i = 1; i <= m; i++) {
        int s = i + k - 1;
        int ss = log[s - i + 1];
        printf("%d ", min(f[i][ss], f[s - (1<<ss) + 1][ss]));
    }
    printf("\n");
    
    //重新再做一遍
    for(int i = 1; i <= n; i++) f[i][0] = a[i];
    for(int j = 1; j <= 20; j++) {
        for(int i = 1; i + (1<<j) -1 <= n; i++) {
            f[i][j] = max(f[i][j-1], f[i + (1<<j-1)][j-1]);
        }
    }
    for(int i = 1; i <= m; i++) {
        int s = i + k - 1;
        int ss = log[s - i + 1];
        printf("%d ", max(f[i][ss], f[s - (1<<ss) + 1][ss]));
    }
    return 0;
}

ST表大法好!!!

标签:洛谷,log,P1886,线段,ST,int,maxn,滑动,include
来源: https://www.cnblogs.com/Benjamin-cpp/p/10371755.html