zoukankan      html  css  js  c++  java
  • 【洛谷 P2216】 [HAOI2007]理想的正方形(二维ST表)

    题目链接
    做出二维(ST)表,然后(O(n^2))扫一遍就好了。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAXN = 1010;
    const int MAXLOGN = 12;
    int Max[MAXN][MAXN][MAXLOGN], Min[MAXN][MAXN][MAXLOGN], Log[MAXN];
    int n, m, k, ans = 2147483647; 
    inline int read(){
        int s = 0, w = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar(); }
        while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }
        return s * w;
    }
    int QueryMin(int x, int y){
    	int p = Log[k];
    	return min(min(Min[x][y][p], Min[x][y + k - (1 << p)][p]),
    	           min(Min[x + k - (1 << p)][y][p], Min[x + k - (1 << p)][y + k - (1 << p)][p]));
    }
    int QueryMax(int x, int y){
    	int p = Log[k];
    	return max(max(Max[x][y][p], Max[x][y + k - (1 << p)][p]),
    	           max(Max[x + k - (1 << p)][y][p], Max[x + k - (1 << p)][y + k - (1 << p)][p]));
    }
    int main(){
    	Log[0] = -1;
    	for(int i = 1; i <= 1000; ++i)
    	   Log[i] = Log[i >> 1] + 1;
    	memset(Max, 128, sizeof Max);
    	memset(Min, 127, sizeof Min);
    	n = read(); m = read(); k = read();
    	for(int i = 1; i <= n; ++i)
    	   for(int j = 1; j <= m; ++j)
    	      Max[i][j][0] = Min[i][j][0] = read();
    	for(int l = 1; l <= 10; ++l)
    	   for(int i = 1; i <= n; ++i)
    	      for(int j = 1; j <= m; ++j){
    	         Max[i][j][l] = max(max(Max[i][j][l - 1], Max[i][min(j + (1 << (l - 1)), m)][l - 1]), 
    			                    max(Max[min(i + (1 << (l - 1)), n)][j][l - 1], Max[min(i + (1 << (l - 1)), n)][min(j + (1 << (l - 1)), m)][l - 1]));
    			 Min[i][j][l] = min(min(Min[i][j][l - 1], Min[i][min(j + (1 << (l - 1)), m)][l - 1]), 
    			                    min(Min[min(i + (1 << (l - 1)), n)][j][l - 1], Min[min(i + (1 << (l - 1)), n)][min(j + (1 << (l - 1)), m)][l - 1]));                   
    		  }
    	for(int i = 1; i + k - 1 <= n; ++i)
    		for(int j = 1; j + k - 1 <= m; ++j)
    		   ans = min(ans, QueryMax(i, j) - QueryMin(i, j));
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    hdu 1296
    hdu 2101
    hdu 2100
    codeforces 3C
    codeforces 2A
    codeforces 1B
    codeforces 811B
    关于sws_scale() 段错误
    cf 1288 D. Minimax Problem (好题)(二分+二进制表状态+枚举)
    opencv4 鼠标事件 鼠标画线条
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/10331593.html
Copyright © 2011-2022 走看看