2019 가축 오프 더 학교 세 번째 F-나무 심기

나무 심기

주제 포털

문제 해결 아이디어

각 하부 경계 열거 한 모든 대응하는 상부 경계를 열거, 최소값, 최대 값 및 최소값이 서서히 갱신 상부 경계로 감소 될 수있는 현재의 경계로서 최대 간격에 대응하는 획득된다. 이 최대 값과 최소값이어서 초기 좌측 경계 설정 단조로운 큐에 배치되고, 우측 경계는 현재로드 지수, 즉이 때 높은 열거 높은이다. 그 최대 값의 위치 및 팀 앞의 최소값, 그리고 어떤 큐 해제 첨자 +1의 좌단이되도록 현재의 최대 및 최소 간격의 차이는, m을 초과 할 경우. 각 영역에 대해 산출 된 조건을 만족하는 최대 값 캔 걸린다.

다음 코드는

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

inline int read(){
    int res = 0, w = 0; char ch = 0;
    while(!isdigit(ch)){
        w |= ch == '-', ch = getchar();
    }
    while(isdigit(ch)){
        res = (res << 3) + (res << 1) + (ch ^ 48);
        ch = getchar();
    }
    return w ? -res : res;
}

const int N = 505;

int a[N][N];
int minn[N], maxx[N];
struct T{
    int i, val;
    T(int val, int i): val(val), i(i){}
};

int main()
{
    int t;
    scanf("%d", &t);
    while(t --){
        int n, m;
        n = read(), m = read();
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= n; j ++)
                a[i][j] = read();
        }
        int ans = 0;
        for(int i = 1; i <= n; i ++){
            for(int j = i; j >= 1; j --){
                if(j == i){
                    for(int k = 1; k <= n; k ++)
                        minn[k] = maxx[k] = a[j][k];
                }
                else {
                    for(int k = 1; k <= n; k ++){
                        minn[k] = min(minn[k], a[j][k]);
                        maxx[k] = max(maxx[k], a[j][k]);
                    }
                }
                int dq1[N], dq2[N];
                int l1, r1, l2, r2;
                l1 = l2 = r1 = r2 = 0;
                int l = 1;
                for(int k = 1; k <= n; k ++){
                    while(l1 != r1 && minn[dq1[r1 - 1]] > minn[k])
                        -- r1;
                    while(l2 != r2 && maxx[dq2[r2 - 1]] < maxx[k])
                        -- r2;
                    dq1[r1 ++] = k;
                    dq2[r2 ++] = k;
                    while(l1 != r1 && l2 != r2 && maxx[dq2[l2]] - minn[dq1[l1]] > m){
                        int x1 = dq1[l1];
                        int x2 = dq2[l2];
                        l = min(x1, x2) + 1;
                        if(x1 <= x2)
                            l1 ++;
                        if(x1 >= x2)
                            l2 ++;
                    }
                    ans = max(ans, (i - j + 1) * (k - l + 1));
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

추천

출처www.cnblogs.com/whisperlzw/p/11248314.html