haoi2007 理想的正方形

链接:https://www.luogu.org/problemnew/show/P2216

题解:维护两次单调队列

代码:

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring> 
#include <iostream>
#define ll long long 
using namespace std;
ll a,b,n,h,h3,t3,h4,t4,f[1022][1022],p1[1022][1022],p2[1022][1022];
ll f1[1022][1022],f2[1022][1022],f3[1022],f4[1022];
ll id1[1022][1022],id2[1022][1022],id3[1022],id4[1022];
ll head1[1022],head2[1022],tail1[1022],tail2[1022];
void insert1(ll x,ll y,ll z)
{
    ll i;
    for (i=tail1[x];i>=head1[x];i--)
    {
        if (f1[x][i]>z) break;
    }
    f1[x][++i]=z;
    tail1[x]=i;
    id1[x][i]=y;
}
void insert2(ll x,ll y,ll z)
{
    ll i;
    for (i=tail2[x];i>=head2[x];i--)
    {
        if (f2[x][i]<z) break;
    }
    f2[x][++i]=z;
    tail2[x]=i;
    id2[x][i]=y;
}
void insert3(ll x,ll y)
{
    ll i;
    for (i=t3;i>=h3;i--)
    {
        if (f3[i]>y) break;
    }
    f3[++i]=y;
    t3=i;
    id3[i]=x;
}
void insert4(ll x,ll y)
{
    ll i;
    for (i=t4;i>=h4;i--)
    {
        if (f4[i]<y) break;
    }
    f4[++i]=y;
    t4=i;
    id4[i]=x;
}
void clear(ll a[1022])
{
    for(ll i=0;i<=1021;i++) a[i]=1;
}
int main()
{
    freopen("noip.in","r",stdin);
    freopen("noip.out","w",stdout);
    ios::sync_with_stdio(false);
  ll ans=999999999;
    memset(f1,-1,sizeof(f1));
    memset(f2,-1,sizeof(f2));
  clear(head1); clear(head2);
    cin>>a>>b>>n;
    for (ll i=1;i<=a;i++)
      for (ll j=1;j<=b;j++)
      {
          cin>>f[i][j];
        }
    for (ll j=1;j<=b;j++)
      for (ll i=1;i<=n-1;i++)
    {
        if (i>=id1[j][head1[j]]+n) head1[j]++;
          insert1(j,i,f[i][j]);
        if (i>=id2[j][head2[j]]+n) head2[j]++;
          insert2(j,i,f[i][j]);
        }    
     for (ll i=1;i<=a-n+1;i++)
     {
       for (ll j=1;j<=b;j++)
      {
            ll ii=i+n-1;
          if (ii>=id1[j][head1[j]]+n) head1[j]++;
            insert1(j,ii,f[ii][j]);
          if (ii>=id2[j][head2[j]]+n) head2[j]++;
            insert2(j,ii,f[ii][j]);
      }
      memset(f3,-1,sizeof(f3));
      memset(f4,-1,sizeof(f4));
      h3=1;t3=0;h4=1;t4=0;
      for (ll j=1;j<=n-1;j++)
      {
        insert3(j,f1[j][head1[j]]);
        insert4(j,f2[j][head2[j]]);
      }
      for (ll j=n;j<=b;j++)
      {
          if (j>=id3[h3]+n) h3++;
          insert3(j,f1[j][head1[j]]);
          if (j>=id4[h4]+n) h4++;
          insert4(j,f2[j][head2[j]]);
          ans=min(ans,f3[h3]-f4[h4]);
        }
  }
  cout<<ans; 
} 
View Code

 

posted @ 2018-01-30 10:42  尹吴潇  阅读(145)  评论(0编辑  收藏  举报