HAOI2007 理想的正方形

传送门

这个题真难写(大雾

其实还是很好想的,因为我们发现每一行的最大/小值是可以用单调队列维护的,每一列的也是可以用单调队列维护的,所以直接用单调队列分别维护行和列即可。

有大神的做法是先把每列的结果处理出来之后计算,我是直接两边一起进行……不过其实都一样,我的代码相比之下要长上一些。单调队列不是很好调,要注意别写错了。

当然这道题st表分别维护行列也是可以过的,不过要慢一点。

看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')

using namespace std;
typedef long long ll;
const int M = 1005;
const int INF = 1000000009;

int read()
{
    int ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
    if(ch == '-') op = -1;
    ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
    ans *= 10;
    ans += ch - '0';
    ch = getchar();
    }
    return ans * op;
}

struct node
{
   int mval,mpos,bval,bpos;
}qy[M][M],qx[M];

int a,b,n,g[M][M],headm[M],tailm[M],headb[M],tailb[M],minn = INF,ansm[1005],ansb[1005];

int main()
{
   a = read(),b = read(),n = read();
   rep(i,1,a)
   rep(j,1,b) g[i][j] = read();
   rep(i,1,b)
   {
      headm[i] = headb[i] = 1,tailm[i] = tailb[i] = 0;
      rep(j,1,n)
      {
     while(headm[i] <= tailm[i] && qy[tailm[i]][i].mval >= g[j][i]) tailm[i]--;
     qy[++tailm[i]][i].mval = g[j][i],qy[tailm[i]][i].mpos = j;
     while(headb[i] <= tailb[i] && qy[tailb[i]][i].bval <= g[j][i]) tailb[i]--;
     qy[++tailb[i]][i].bval = g[j][i],qy[tailb[i]][i].bpos = j;
      }
      //ansm[i] = qy[headm][i].mval,ansm;
   }
   //rep(i,1,b) printf("#%d %d\n",qy[headm[i]][i].mval,qy[headb[i]][i].bval);
   rep(t,n+1,a+1)
   {
      headm[0] = headb[0] = 1,tailm[0] = tailb[0] = 0;
      rep(i,1,b)
      {
     while(headm[0] <= tailm[0] && qx[tailm[0]].mval >= qy[headm[i]][i].mval) tailm[0]--;
     qx[++tailm[0]].mval = qy[headm[i]][i].mval,qx[tailm[0]].mpos = i;
     while(headm[0] <= tailm[0] && qx[headm[0]].mpos < qx[tailm[0]].mpos - n + 1) headm[0]++;
     while(headb[0] <= tailb[0] && qx[tailb[0]].bval <= qy[headb[i]][i].bval) tailb[0]--;
     qx[++tailb[0]].bval = qy[headb[i]][i].bval,qx[tailb[0]].bpos = i;
     while(headb[0] <= tailb[0] && qx[headb[0]].bpos < qx[tailb[0]].bpos - n + 1) headb[0]++;
     if(i >= n)
     {
        //printf("$%d %d\n",qx[headb[0]].bval,qx[headm[0]].mval);
        minn = min(minn,qx[headb[0]].bval - qx[headm[0]].mval);
     }
     while(headm[i] <= tailm[i] && qy[tailm[i]][i].mval >= g[t][i]) tailm[i]--;
     qy[++tailm[i]][i].mval = g[t][i],qy[tailm[i]][i].mpos = t;
     while(headm[i] <= tailm[i] && qy[headm[i]][i].mpos < t - n + 1) headm[i]++;
     while(headb[i] <= tailb[i] && qy[tailb[i]][i].bval <= g[t][i]) tailb[i]--;
     qy[++tailb[i]][i].bval = g[t][i],qy[tailb[i]][i].bpos = t;
     while(headb[i] <= tailb[i] && qy[headb[i]][i].bpos < t - n + 1) headb[i]++;
      }
   }
   printf("%d\n",minn);
   return 0;
}

 

posted @ 2018-11-08 15:25  CaptainLi  阅读(138)  评论(0编辑  收藏  举报