More than 2019 cattle off summer school camp (third) F Planting Trees monotonous queue

F Planting Trees

Topic Link

https://ac.nowcoder.com/acm/contest/883/F

Title Description

The semester is finally over and the summer holiday is coming. However, as part of your university's graduation requirement, you have to take part in some social service during the holiday. Eventually, you decided to join a volunteer group which will plant trees in a mountain.
To simplify the problem, let's represent the mountain where trees are to be planted with an \(N \times N\) grid. Let's number the rows \(\ 1\) to \(\ N\) from top to bottom, and number the columns \(\ 1\) to \(\ N\) from left to right. The elevation of the cell in the \(\ i\)-th row and \(\ j\)-th column is denoted by \(a_{i,j}\). Your leader decides that trees should be planted in a rectangular area within the mountain and that the maximum difference in elevation among the cells in that rectangle should not exceed M. In other words, if the coordinates of the top-left and the bottom-right corners of the rectangle are \((x_1,y_1)\) and \((x_2,y_2)\), then the condition $ |a_{i,j} - a_{k,l}| \le M$ must hold for \(x_1 \le i,k \le x_2, \ y_1 \le j,l \le y_2\). Please help your leader calculate the maximum possible number of cells in such a rectangle so that he'll know how many trees will be planted.

Enter a description:

The input contains multiple cases. The first line of the input contains a single integer \(T\ (1 \le T \le 1000)\), the number of cases.
For each case, the first line of the input contains two integers $ N (1 \le N \le 500)$ and \(M\ (0 \le M \le 10^5)\). The following N lines each contain N integers, where the\(\ j-th\) integer in the i i i-th line denotes \(a_{i,j} \ (1 \le a_{i,j} \le 10^5)\).
It is guaranteed that the sum of \(N^3\) over all cases does not exceed \(25 \cdot 10^7\).

Output Description:

For each case, print a single integer, the maximum number of cells in a valid rectangle.

Entry

    2
    2 0
    1 2
    2 1
    3 1
    1 3 2
    2 3 1
    3 2 1

Export

    1
    4

The meaning of problems

You give a \ (N \ times N \) matrix, a self-seeking the most submatrix matrices satisfying the maximum and minimum're just less than m.

answer

A decent look at the last sentence, wondered that \ (n ^ 3 \) algorithm, so it is natural to think of \ (n ^ 2 \) enumeration and the previous lower bound, then \ (n \) to scan again.

If we think determines the upper and lower bounds, then we enumerate the left boundary, right boundary as long as possible, then to the left edge of the right time, the right border will not be to the left (there should not be difficult want, whenever you want to certainly not hard to think), this seems to be called the ruler emulated.

The rest is the minimum and maximum range of requirements, and I began to direct a two-dimensional double, the result of a timeout, changed two hours or overtime, only to give up. Followed by the monotony of the queue to seek minimum and maximum values, this approach feels very classic, but I did not see it, or do a few topics.

Briefly talk monotone queue:

We engage in two queues, one for selecting the maximum value, the minimum required for other

The first step: remove the illegal head of the queue (change the left margin)

Part II: extending back right border

Part III: Update answers

So talk a little abstract, and then I went to find the basis of title, finished basic problem, this also will be a natural.

AC Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x7f7f7f7f
#define N 505
#define maxx(a,b) a<b?b:a
#define minn(a,b) a<b?a:b
int n,m,mx[N],mi[N],a[N][N];
struct Queue{int val,id;}Q1[N],Q2[N];
clock_t now;
template<typename T>void read(T&x)
{
    ll k=0; char c=getchar();
    x=0;
    while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
    if (c==EOF)exit(0);
    while(isdigit(c))x=x*10+c-'0',c=getchar();
    x=k?-x:x;
}
inline void work()
{
    now=clock();
    int ans=1;
    read(n); read(m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            read(a[i][j]);
    for(int i=1;i<=n;i++)
        for(int j=i;j<=n;j++)
        {
            int ds1=1,dw1=0,ds2=1,dw2=0,r=0;
            for(int k=1;k<=n;k++)
            {
                if (i==j)mx[k]=mi[k]=a[i][k];
                else {mx[k]=maxx(mx[k],a[j][k]);mi[k]=minn(mi[k],a[j][k]);}
            }
            for(int k=1;k<=n;k++)
            {
                r=maxx(r,k-1);
                while(ds1<=dw1&&Q1[ds1].id<k)ds1++;
                while(ds2<=dw2&&Q2[ds2].id<k)ds2++;
                if (mx[k]-mi[k]>m)continue;
                int m1=maxx(mx[r+1],Q1[ds1].val);
                int m2=minn(mi[r+1],Q2[ds2].val);
                if (ds1>dw1)m1=mx[r+1],m2=mi[r+1];
                while(r+1<=n&&(mx[r+1]-mi[r+1]<=m)&&(ds1>dw1||m1-m2<=m))
                    {
                        while(mx[r+1]>Q1[dw1].val&&ds1<=dw1)dw1--;
                        while(mi[r+1]<Q2[dw2].val&&ds2<=dw2)dw2--;
                        Q1[++dw1]={mx[r+1],r+1};
                        Q2[++dw2]={mi[r+1],r+1};
                        r++;
                        m1=maxx(m1,mx[r+1]);
                        m2=minn(m2,mi[r+1]);
                    }
                ans=maxx(ans,(j-i+1)*(r-k+1));
            }

        }
    printf("%d\n",ans);
    //cout<<(double)(clock()-now)/CLOCKS_PER_SEC*1000<<endl;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("aa.in","r",stdin);
    #endif
    int T;
    read(T);
    while(T--)work();
}

Timeout Code (only viewing)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x7f7f7f7f
#define N 505
int n,m,mx[N][N][10][10],mi[N][N][10][10],mm[N],mv[10];
template<typename T>void read(T&x)
{
    ll k=0; char c=getchar();
    x=0;
    while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
    if (c==EOF)exit(0);
    while(isdigit(c))x=x*10+c-'0',c=getchar();
    x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
void build_ST()
{
    for(int i=2;i<=n;i++)mm[i]=mm[i>>1]+1;
    for(int i=0;i<=10;i++)mv[i]=1<<i;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            mx[i][j][0][0]=mi[i][j][0][0];
    for(int k=1;k<=8;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j+(1<<k)-1<=n;j++)
            {
                mx[i][j][0][k]=max(mx[i][j][0][k-1],mx[i][j+(1<<(k-1))][0][k-1]);
                mi[i][j][0][k]=min(mi[i][j][0][k-1],mi[i][j+(1<<(k-1))][0][k-1]);
            }
                      
    for(int k1=1;k1<=8;k1++)
        for(int k2=0;k2<=8;k2++)
            for(int i=1;i+(1<<k1)-1<=n;i++)
                for(int j=1;j+(1<<k2)-1<=n;j++)
                {
                    mx[i][j][k1][k2]=
                        max(mx[i][j][k1-1][k2],mx[i+(1<<(k1-1))][j][k1-1][k2]);
                    mi[i][j][k1][k2]=
                        min(mi[i][j][k1-1][k2],mi[i+(1<<(k1-1))][j][k1-1][k2]);
                }
      
}
inline int get_mx(int x1,int y1,int x2,int y2)
{
    int k1=mm[x2-x1+1],k2=mm[y2-y1+1];
    x2=x2-mv[k1]+1;
    y2=y2-mv[k2]+1;
    int a1=max(mx[x1][y1][k1][k2],mx[x1][y2][k1][k2]);
    int a2=max(mx[x2][y1][k1][k2],mx[x2][y2][k1][k2]);
    return max(a1,a2);
}
inline int get_mi(int x1,int y1,int x2,int y2)
{
    int k1=mm[x2-x1+1],k2=mm[y2-y1+1];
    x2=x2-(1<<k1)+1;
    y2=y2-(1<<k2)+1;
    int a1=min(mi[x1][y1][k1][k2],mi[x1][y2][k1][k2]);
    int a2=min(mi[x2][y1][k1][k2],mi[x2][y2][k1][k2]);
    return min(a1,a2);
}
void work()
{
    int ans=1;
    read(n); read(m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            read(mi[i][j][0][0]);
    build_ST();
    for(int i=1;i<=n;i++)
        for(int j=i;j<=n;j++)
        {
            int l=1;
            for(int k=1;k<=n;k++)
            {
                int mx=get_mx(i,l,j,k);
                int mi=get_mi(i,l,j,k);
                while(mx-mi>m&&l<=k)
                {
                    l++;
                    if(l<=k)mx=get_mx(i,l,j,k);
                    if(l<=k)mi=get_mi(i,l,j,k);
                }
                ans=max(ans,(j-i+1)*(k-l+1));
            }
        }
    printf("%d\n",ans);
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("aa.in","r",stdin);
#endif
    int T;
    read(T);
    while(T--)work();
}

Guess you like

Origin www.cnblogs.com/mmmqqdd/p/11247624.html