现在的位置: 首页 > 综合 > 正文

[HAOI2007]理想的正方形

2015年04月22日 ⁄ 综合 ⁄ 共 1687字 ⁄ 字号 评论关闭

果然我只会做水题233还写了好久

一开始用multisetTLE,结果是BZOJ题面数据范围小了233

然后发现我没有学过单调队列233

固定区间最大/最小值,用单调队列优化至O(n)

这个题先处理出f[i][j]表示(i,j)到(i+n-1,j)的最大/最小值

再用f处理出max/min[i][j]表示(i,j)到(i+n-1,j+n-1)的最大/最小值

然后WA的不能自理然后发现打错了变量名233

Code:(自己YY的单调队列好丑233)

#include <cstdio>
#include <algorithm>
using namespace std;
#define N 1001
int d[N][N], n, m, k;
char c;
int ma[N][N], mi[N][N], ans(0x7fffffff);
int fma[N][N], fmi[N][N];
inline void read(int &x)
{
    int opt(1);
    for (c = getchar();c > '9' || c < '0';c = getchar())
        if (c == '-')opt = -1;
    for (x = 0;c >= '0' && c <= '9';c = getchar())
        x = (x << 3) + (x << 1) + c - '0';
    x *= opt;
}
struct Item
{
    int i, d;
    Item(int _i = 0, int _d = 0){i = _i, d = _d;}
};
struct max_queue
{
    Item q[N];
    int head, tail;
    void push(int i, int x)
    {
        while (head < tail && q[tail-1].d <= x)
            tail--;
        q[tail++] = Item(i, x);
    }
    void clear()
    {
        head = tail = 0;
        q[head] = Item(0, 0);
    }
    int qmax(int l)
    {
        while (head < tail && q[head].i < l)
            head++;
        return q[head].d;
    }
}qma;
struct min_queue
{
    Item q[N];
    int head, tail;
    void push(int i, int x)
    {
        while (head < tail && q[tail-1].d >= x)
            tail--;
        q[tail++] = Item(i, x);
    }
    void clear()
    {
        head = tail = 0;
        q[head] = Item(0, 0);
    }
    int qmin(int l)
    {
        while (head < tail && q[head].i < l)
            head++;
        return q[head].d;
    }
}qmi;
void work()
{
    int i, j;
    for (i = 1;i <= n; ++i)
    {
        qma.clear(), qmi.clear();
        for (j = 1;j < k; ++j)
            qma.push(j, d[i][j]), qmi.push(j, d[i][j]);
        for (j = k;j <= m; ++j)
        {
            qma.push(j, d[i][j]), qmi.push(j, d[i][j]);
            fma[i][j-k+1] = qma.qmax(j-k+1), fmi[i][j-k+1] = qmi.qmin(j-k+1);
        }
    }
    for (j = 1;j <= m; ++j)
    {
        qma.clear(), qmi.clear();
        for (i = 1;i < k; ++i)
            qma.push(i, fma[i][j]), qmi.push(i, fmi[i][j]);
        for (i = k;i <= n; ++i)
        {
            qma.push(i, fma[i][j]), qmi.push(i, fmi[i][j]);
            ma[i-k+1][j] = qma.qmax(i-k+1), mi[i-k+1][j] = qmi.qmin(i-k+1);
        }
    }
    for (i = 1;i + k - 1 <= n; ++i)
        for (j = 1;j + k - 1 <= m; ++j)
            ans = min(ans, ma[i][j] - mi[i][j]);
    printf("%d", ans);
}
int main()
{
    int i, j;
    read(n), read(m), read(k);
    for (i = 1;i <= n; ++i)
        for (j = 1;j <= m; ++j)
            read(d[i][j]);
    work();
}

抱歉!评论已关闭.