Luo Gu P2216 [HAOI2007] ideal square

Luo Gu P2216 [HAOI2007] ideal square

Description

  • A has a matrix composed of integer b, from which you now find an n square region of n so as to minimize the difference in the number of all the regions of maximum and minimum values.

Input

  • The first behavior three integers, represent the values ​​a, b, n of

    The second line to the first line of each conduct a + 1 b non-negative integer, the number of the corresponding position in the matrix indicates. Each line separated by a space between adjacent two numbers.

Output

  • Only an integer, a is all "n matrix B minimum difference between the maximum and the minimum integer n integer square region," the.

Sample Input

5 4 2

1 2 5 6

0 17 16 0

16 17 2 1

2 10 2 1

1 2 2 2

Sample Output

1

answer:

  • Monotone queue.
  • A situation got out and comfortable.
  • For obtaining a maximum of n * n rectangle may be thought of as the maximum value and the maximum value of each row in the n-th row. The maximum value of each row how demand? Segment tree, ST tables are OK. But is it better monotone queue?
  • So the first queue determined monotonous point (i, j) is the i-th row j - n + 1 maximum / minimum value of the lattice j ~ .
  • So for a rectangle we just need to enumerate n times you can get the maximum / minimum value of.
  • However, you draw range n * n rectangle marquee with pen and paper. Can be found in each rectangle is the whole move down a grid. So this is a monotonous queue Yeah. But this is monotonous queue element to point (i, j) is the i-th row j - n + 1 ~ maximum / minimum value j of the trellis .
  • Complexity is about O (2ab) = O (n ^ 2 scale).
  • Oh, I get lazy with STL, a huge constant. Not open O2 90pts, open the O2 can A.
#include <iostream>
#include <cstdio>
#include <queue>
#define N 1005
#define inf 0x7fffffff
using namespace std;

struct Node1
{
    int val, pos;
    friend bool operator < (Node1 x, Node1 y) {
        return x.val < y.val;
    }
};
struct Node2
{
    int val, pos;
    friend bool operator < (Node2 x, Node2 y) {
        return x.val > y.val;
    }
};
int n, m, len, ans = inf;
int Max[N][N], Min[N][N];

int read()
{
    int x = 0; char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x;
}

int main()
{
    cin >> n >> m >> len;
    for(int i = 1; i <= n; i++)
    {
        priority_queue<Node1> que1;
        priority_queue<Node2> que2;
        for(int j = 1; j < len; j++)
        {
            int x = read();
            que1.push((Node1){x, j});
            que2.push((Node2){x, j});
        }
        for(int j = len; j <= m; j++)
        {
            while(que1.size() && que1.top().pos <= j - len) que1.pop();
            while(que2.size() && que2.top().pos <= j - len) que2.pop();
            int x = read();
            que1.push((Node1){x, j});
            que2.push((Node2){x, j});
            Max[i][j] = que1.top().val;
            Min[i][j] = que2.top().val;
        }
    }
    for(int j = len; j <= m; j++)
    {
        priority_queue<Node1> que1;
        priority_queue<Node2> que2;
        for(int i = 1; i < len; i++)
        {
            int v1 = Max[i][j];
            int v2 = Min[i][j];
            que1.push((Node1){v1, i});
            que2.push((Node2){v2, i});
        }
        for(int i = len; i <= n; i++)
        {
            while(que1.size() && que1.top().pos <= i - len) que1.pop();
            while(que2.size() && que2.top().pos <= i - len) que2.pop();
            int v1 = Max[i][j];
            int v2 = Min[i][j];
            que1.push((Node1){v1, i});
            que2.push((Node2){v2, i});
            ans = min(ans, que1.top().val - que2.top().val);
        }
    }
    cout << ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/BigYellowDog/p/11514929.html