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 @   CaptainLi  阅读(138)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示