[HAOI2007]理想的正方形

来源:互联网 发布:万州房地产数据 编辑:程序博客网 时间:2024/05/01 18:15

果然我只会做水题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 1001int 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();}

0 0
原创粉丝点击