[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;
}

 

  

posted @ 2017-04-19 14:12  2+c  阅读(364)  评论(0编辑  收藏  举报