1. 程式人生 > >P2216 [HAOI2007]理想的正方形 [二維RMQ]

P2216 [HAOI2007]理想的正方形 [二維RMQ]

com 最值 int 參考文獻 -h main pan bits del

P2216 [HAOI2007]理想的正方形

這道題就是標準的二維RMQ模板。

回顧一下原來的RMQ,分兩個階段,先倍增的初始化,再\(O(1)\)地求答案。二維RMQ也是有異曲同工之妙的。

這個最值怎麽定義?我們設\(maxv[i][j][k]\)為以\((i,j)\)為左上角的\(2^k\times 2^k\)正方形區域中的最大值。最小值同理,下面都只討論最大值。

怎麽初始化?我們同樣枚舉\(k\)。一維RMQ通過枚舉\(k\)變成兩段,二維RMQ就會變成四個。都取最大值就是了。

怎麽求答案?同樣\(O(1)\)地算出\(n\)對應的\(k\),然後同樣取四個ST表得到最大值。

基本原理跟一維RMQ是完全一致的,唯一的不同就是需要討論4種,僅此而已。

好好看代碼8:

#include<bits/stdc++.h>
const int maxn = 1002;
const int INF = 0x3f3f3f3f;
int maxv[12][maxn][maxn], minv[12][maxn][maxn];
int a, b, n;
int ans = INF;
int main() {
    scanf("%d %d %d", &a, &b, &n);
    for(int i = 1; i <= a; i++) {
        for(int j = 1; j <= b; j++) {
            scanf("%d", &maxv[0][i][j]);
            minv[0][i][j] = maxv[0][i][j];
        }
    }
    for(int k = 1; (1 << k) <= n; k++) {
        for(int i = 1; i + (1 << k) - 1 <= a; i++) {
            for(int j = 1; j + (1 << k) - 1 <= b; j++) {
                maxv[k][i][j] = std::max(std::max(maxv[k - 1][i][j], maxv[k - 1][i + (1 << (k - 1))][j]), std::max(maxv[k - 1][i][j + (1 << (k - 1))], maxv[k - 1][i + (1 << (k - 1))][j + (1 << (k - 1))]));
                minv[k][i][j] = std::min(std::min(minv[k - 1][i][j], minv[k - 1][i + (1 << (k - 1))][j]), std::min(minv[k - 1][i][j + (1 << (k - 1))], minv[k - 1][i + (1 << (k - 1))][j + (1 << (k - 1))]));
            }
        }
    }
    int k = 0;
    while((1 << (k + 1)) <= n) k++;
    for(int i = 1; i + n - 1 <= a; i++) {
        for(int j = 1; j + n - 1 <= b; j++) {
            int max = std::max(std::max(maxv[k][i][j], maxv[k][i + n - (1 << k)][j]), std::max(maxv[k][i][j + n - (1 << k)], maxv[k][i + n - (1 << k)][j + n - (1 << k)]));
            int min = std::min(std::min(minv[k][i][j], minv[k][i + n - (1 << k)][j]), std::min(minv[k][i][j + n - (1 << k)], minv[k][i + n - (1 << k)][j + n - (1 << k)]));
            ans = std::min(ans, max - min);
        }
    }
    printf("%d\n", ans);
}

參考文獻:https://www.cnblogs.com/GXZlegend/p/7491533.html

這篇博客的代碼真的漂亮。

漂亮警告

P2216 [HAOI2007]理想的正方形 [二維RMQ]