• 洛谷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("
    ");
        
        //重新再做一遍
        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表大法好!!!

    唯愿,青春不辜负梦想,未来星辰闪耀
  • 相关阅读:
    电赛小结
    markdown小结
    一元运算符重载
    二维数组作为函数参数传递剖析(转载)
    C语言内存(转载)
    Effective C++ chapter1:Accustiming Yourself to C++
    C++ 模板
    const
    命令行参数
    AStar算法
  • 原文地址:https://www.cnblogs.com/Benjamin-cpp/p/10371755.html
Copyright © 2020-2023  润新知