zoukankan      html  css  js  c++  java
  • 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('
    ')
    
    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
    ",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
    ",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
    ",minn);
       return 0;
    }
  • 相关阅读:
    将SL4 程序移植到WP7(附Teched2010“.NET研究”真机图) 狼人:
    WP7有约(二“.NET研究”):课后作业 狼人:
    Android平台SQLite快速入门“.NET研究”实践 狼人:
    移动Web界面构建最佳“.NET研究”实践 狼人:
    Androi“.NET研究”d如何在三年时间里征服移动世界的 狼人:
    详解如何让Android UI“.NET研究”设计性能更高效 狼人:
    Android 2.3预计下周发布 十大惊“.NET研究”喜不容错过 狼人:
    Android的移动存储解决方案“.NET研究”之SharedPreferences 狼人:
    C++开发者快速学习ObjectiveC语言核“.NET研究”心语法 狼人:
    图像像素OpenCV4Android一点关于图像的基础
  • 原文地址:https://www.cnblogs.com/captain1/p/9929300.html
Copyright © 2011-2022 走看看