[HAOI2017]理想的正方形codevs1715
二维RMQ,算是暴力做法,洛谷 codevs可以A掉90%,bzoj居然全A 玄学,剩下一个TLE的点需要单调队列+滑动窗口
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #define N 1501 using namespace std; int a,b,n; int minn[N][N][13],maxx[N][N][13]; int main() { // memset(maxx,127,sizeof(maxx)); // memset(minn,-127,sizeof(minn)); scanf("%d %d %d",&a,&b,&n); for(int i=1;i<=a;i++) for(int j=1;j<=b;j++) { scanf("%d",&maxx[i][j][0]); minn[i][j][0]=maxx[i][j][0]; } int k=log2(max(a,b)); for(int pow=1;pow<=k;pow++) { int len=1<<(pow-1); for(int i=1;i;i++) { if(i+len>a) break; for(int j=1;j;j++) { if(j+len>b) break; maxx[i][j][pow]=max(max(maxx[i][j][pow-1],maxx[i+len][j][pow-1]),max(maxx[i+len][j+len][pow-1],maxx[i][j+len][pow-1])); minn[i][j][pow]=min(min(minn[i][j][pow-1],minn[i+len][j][pow-1]),min(minn[i+len][j+len][pow-1],minn[i][j+len][pow-1])); } } } k=log2(n); int len=1<<k,ans=0x7fffffff; for(int i=1;i;i++) { if(i+n-1>a)break; for(int j=1;j;j++) { if(j+n-1>b) break; int ma,mi; ma=max(max(maxx[i][j][k],maxx[i+n-len][j][k]),max(maxx[i][j+n-len][k],maxx[i+n-len][j+n-len][k])); mi=min(min(minn[i][j][k],minn[i+n-len][j][k]),min(minn[i][j+n-len][k],minn[i+n-len][j+n-len][k])); if(ans>ma-mi) ans=ma-mi; } } printf("%d",ans); return 0; }