• BZOJ 1047 [HAOI2007]理想的正方形 单调队列DP


    题解:

    刚睡醒写的,总是看不清括号。。。调了半天。。

    就是横向一个掉队列,纵向b个单调队列,n^2的求出以(i,j)点为右下角的n*n矩形的最大值和最小值,然后n^2的统计就好~

    View Code
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cstdio>
     5 #include <algorithm>
     6 
     7 #define N 1111
     8 #define BUG system("pause")
     9 
    10 using namespace std;
    11 
    12 long long a,b,n;
    13 long long map[N][N];
    14 long long q[N][N],h[N],t[N],s,e,dq[N];
    15 long long mx[N][N],ans,mn[N][N];
    16 
    17 inline void read()
    18 {
    19     scanf("%lld%d%d",&a,&b,&n);
    20     for(long long i=1;i<=a;i++)
    21         for(long long j=1;j<=b;j++)
    22             scanf("%lld",&map[i][j]);
    23 }
    24 
    25 inline void getmax()
    26 {
    27     for(long long i=1;i<=b;i++) h[i]=1,t[i]=0;
    28     for(long long i=1;i<=a;i++)
    29     {
    30         for(long long j=1;j<=b;j++)
    31         {
    32             
    33             while(h[j]<=t[j]&&i-q[j][h[j]]+1>n) h[j]++;
    34             while(h[j]<=t[j]&&map[q[j][t[j]]][j]<=map[i][j]) t[j]--;
    35             q[j][++t[j]]=i;    
    36         }
    37         e=0; s=1;
    38         for(long long j=1;j<=b;j++)
    39         {
    40             while(s<=e&&j-dq[s]+1>n) s++;
    41             while(s<=e&&map[q[dq[e]][h[dq[e]]]][dq[e]]<=map[q[j][h[j]]][j]) e--;
    42             dq[++e]=j;
    43             mx[i][j]=map[q[dq[s]][h[dq[s]]]][dq[s]];
    44         }
    45     }
    46 }
    47 
    48 inline void getmin()
    49 {
    50     for(long long i=1;i<=b;i++) h[i]=1,t[i]=0;
    51     for(long long i=1;i<=a;i++)
    52     {
    53         for(long long j=1;j<=b;j++)
    54         {
    55             while(h[j]<=t[j]&&i-q[j][h[j]]+1>n) h[j]++;
    56             while(h[j]<=t[j]&&map[q[j][t[j]]][j]>=map[i][j]) t[j]--;
    57             q[j][++t[j]]=i;    
    58         }
    59         e=0; s=1;
    60         for(long long j=1;j<=b;j++)
    61         {
    62             while(s<=e&&j-dq[s]+1>n) s++;
    63             while(s<=e&&map[q[dq[e]][h[dq[e]]]][dq[e]]>=map[q[j][h[j]]][j]) e--;
    64             dq[++e]=j;
    65             mn[i][j]=map[q[dq[s]][h[dq[s]]]][dq[s]];
    66         }
    67     }
    68 }
    69 
    70 inline void go()
    71 {
    72     getmin();
    73     getmax();
    74     ans=1LL<<60;
    75     for(long long i=n;i<=a;i++)
    76         for(long long j=n;j<=b;j++)
    77             ans=min(ans,mx[i][j]-mn[i][j]);
    78     printf("%lld\n",ans);
    79 }
    80 
    81 int main()
    82 {
    83     read(),go();
    84     return 0;
    85 }
  • 相关阅读:
    PHP中GBK和UTF8乱码解决方案
    Ubuntu下的PHP开发环境架设
    Windows 7 IE主页被篡改,如何修复?
    提高代码质量:如何编写函数
    PhpStorm 10 破解方法
    PHP 常用的header头部定义汇总
    kindle 退出演示模式
    好程序与差程序Good Programming, Bad Programming
    如何让你的一天能有26小时?不完全是开玩笑
    毕业若干年,才知道自己原来认为的很多都是错的想法的成熟
  • 原文地址:https://www.cnblogs.com/proverbs/p/2945108.html
Copyright © 2020-2023  润新知