也是单调队列
我之前分别用了优先队列和二位rmq做这题都超时了。。
最后学习了别人的题解
#include<bits/stdc++.h>
using namespace std;
#define sz(X) ((int)X.size())
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
const int N = 1e3+5;
const int INF = 0x3f3f3f3f;
int a,b,n;
int mp[N][N], mx[N][N], mi[N][N], t1[N], t2[N];
int ans;
int val[N], pos[N];
void pre() {
for(int i = 1; i <= a; ++i) {
int l = 1; int r = 1;
for(int j = 1; j <= b; ++j) {
while(l < r && val[r-1]<=mp[i][j]) r--;
val[r]=mp[i][j]; pos[r] = j; r++;
if(pos[l] == j-n) l++;
if(j >= n) mx[i][j] = val[l];
}
l = 1; r = 1;
for(int j = 1; j <= b; ++j) {
while(l < r && val[r-1]>=mp[i][j]) r--;
val[r]=mp[i][j]; pos[r] = j; r++;
if(pos[l] == j-n) l++;
if(j >= n) mi[i][j] = val[l];
}
}
}
void solve() {
for(int i = n; i <= b; ++i) {
int l = 1; int r = 1;
for(int j = 1; j <= a; ++j) {
while(l < r && val[r-1]<=mx[j][i]) r--;
val[r]=mx[j][i]; pos[r]=j; r++;
if(pos[l] == j-n) l++;
if(j >= n) t1[j] = val[l];
}
l = 1; r = 1;
for(int j = 1; j <= a; ++j) {
while(l < r && val[r-1]>=mi[j][i]) r--;
val[r]=mi[j][i]; pos[r]=j; r++;
if(pos[l] == j-n) l++;
if(j >= n) t2[j] = val[l];
}
for(int j = n; j <= a; ++j) ans = min(ans, abs(t1[j]-t2[j]) );
}
}
int main(){
while(~scanf("%d %d %d",&a,&b,&n)) {
for(int i = 1; i <= a; ++i)
for(int j = 1; j <= b; ++j)
scanf("%d",&mp[i][j]);
ans = INF;
pre();
solve();
printf("%d\n",ans);
}
return 0;
}