给定一个n * n的矩阵,和一个整数B, K次询问,每次询问给出一对x,y
求以x y为左上角的B * B的子矩阵中的最大差值是多少
1 <= N <= 250, 1 <= K <= 100000, 1 <= B <= N
本题难度并不大,但是要注意将差值拆成最大值与最小值维护这个方法。
#include<cstdio> #include<iostream> #include<cmath> #include<queue> #include<vector> #include<cstring> #include<algorithm> #include<map> #include<set> #include<stack> #include<sstream> #include<string> using namespace std; #define inf 0x3f3f3f3f int maxn[260][260][15]; int miin[260][260][15]; int n,b,k; void init() { int len=floor(log10(double(n))/log10(double(2))); for(int i=1;i<=n;i++)//行 { for(int k=1;k<=len;k++)//倍增 { for(int j=1;j+(1<<k)-1<=n;j++) { maxn[i][j][k]=max(maxn[i][j][k-1],maxn[i][j+(1<<(k-1))][k-1]); miin[i][j][k]=min(miin[i][j][k-1],miin[i][j+(1<<(k-1))][k-1]); } } } } int main() { scanf("%d%d%d",&n,&b,&k); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&maxn[i][j][0]); miin[i][j][0]=maxn[i][j][0]; } } init(); int len=floor(log10(double(b))/log10(double(2))); for(int i=1;i<=k;i++) { int x,y; scanf("%d%d",&x,&y); int mx=-0x3f3f3f3f,mi=0x3f3f3f3f; for(int i=x;i<x+b;i++) { mx=max(max(maxn[i][y][len],maxn[i][b+y-(1<<len)][len]),mx); mi=min(min(miin[i][y][len],miin[i][b+y-(1<<len)][len]),mi); } printf("%d\n",mx-mi); } return 0; }
原文:https://www.cnblogs.com/EDawnpractice/p/14144989.html