Submission #1181833

#TimeUsernameProblemLanguageResultExecution timeMemory
1181833bbartekSandcastle 2 (JOI22_ho_t5)C++20
0 / 100
5099 ms130752 KiB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
#define st first
#define nd second
#define pb push_back

const int maxn = 5e4+7;

int n,m;
vector<int> tab[maxn];
vector<int> sumy[3][3][3][3][maxn]; //gora/dol/lewo/prawo

int sprawdz(int a,int b,int c,int d,int i,int j){
    if(i+a > n || i-b < 1 || j+a > m || j-a < 1)
        return 0;
    int maks,odp=0;
    if(a > 0 && tab[i+1][j] < tab[i][j]){
        maks = 0;
        if(a == 2)
            maks = max(maks,tab[i+2][j]);
        if(c > 0)
            maks = max(maks,tab[i+1][j-1]);
        if(d > 0)
            maks = max(maks,tab[i+1][j+1]);

        if(maks < tab[i][j])
            odp++;
    }
    if(b > 0 && tab[i-1][j] < tab[i][j]){
        maks = 0;
        if(b == 2)  
            maks = max(maks,tab[i-2][j]);
        if(c > 0)
            maks = max(maks,tab[i-1][j-1]);
        if(d > 0)
            maks = max(maks,tab[i-1][j+1]);

        if(maks < tab[i][j])
            odp++;
    }
    if(c > 0 && tab[i][j-1] < tab[i][j]){
        maks = 0;
        if(c == 2)  
            maks = max(maks,tab[i][j-2]);
        if(a > 0)
            maks = max(maks,tab[i-1][j-1]);
        if(b > 0)
            maks = max(maks,tab[i+1][j-1]);

        if(maks < tab[i][j])
            odp++;
    }
    if(d > 0 && tab[i][j+1] < tab[i][j]){
        maks = 0;
        if(d == 2)  
            maks = max(maks,tab[i][j+2]);
        if(a > 0)
            maks = max(maks,tab[i-1][j+1]);
        if(b > 0)
            maks = max(maks,tab[i+1][j+1]);

        if(maks < tab[i][j])
            odp++;
    }

    return odp;
}

int odczytaj_sume(int a,int b,int c,int d,int a1,int b1,int a2,int b2){
    return sumy[a][b][c][d][a2][b2] - sumy[a][b][c][d][a1-1][b2] - sumy[a][b][c][d][a2][b1-1] + sumy[a][b][c][d][a1-1][b1-1];
}

vector<bool> odwiedzone[maxn];
ll licznik = 0;
void dfs(int a1,int b1,int a2,int b2,int i,int j){
    odwiedzone[i][j] = 1;
    licznik++;
    int maks = 0,ind=0;
    if(i>a1 && tab[i-1][j] > maks && tab[i-1][j] < tab[i][j]){
        maks = tab[i-1][j];
        ind = 1;
    }
    if(i<a2 && tab[i+1][j] > maks && tab[i+1][j] < tab[i][j]){
        maks = tab[i+1][j];
        ind = 2;
    }
    if(j>b1 && tab[i][j-1] > maks && tab[i][j-1] < tab[i][j]){
        maks = tab[i][j-1];
        ind = 3;
    }
    if(j<b2 && tab[i][j+1] > maks && tab[i][j+1] < tab[i][j]){
        maks = tab[i][j+1];
        ind = 4; 
    }
    if(ind == 1){
        if(odwiedzone[i-1][j])
            return;
        dfs(a1,b1,a2,b2,i-1,j);
    } 
    if(ind == 2){
        if(odwiedzone[i+1][j])
            return;
        dfs(a1,b1,a2,b2,i+1,j);
    } 
    if(ind == 3){
        if(odwiedzone[i][j-1])
            return;
        dfs(a1,b1,a2,b2,i,j-1);
    } 
    if(ind == 4){
        if(odwiedzone[i][j+1])
            return;
        dfs(a1,b1,a2,b2,i,j+1);
    }
    return;
}

bool czyzjazd(int a1,int b1,int a2,int b2){
    int suma=0;
    if((a2-a1) >= 4 && (b2-b1) >= 4){
        //srodek
        suma += odczytaj_sume(2,2,2,2,a1+2,b1+2,a2-2,b2-2);
        //boki wewnatrz
        suma += odczytaj_sume(1,2,2,2,a1+1,b1+2,a1+1,b2-2);
        suma += odczytaj_sume(2,1,2,2,a2-1,b1+2,a2-1,b2-2);
        suma += odczytaj_sume(2,2,1,2,a1+2,b1+1,a2-2,b1+1);
        suma += odczytaj_sume(2,2,2,1,a1+2,b2-1,a2-2,b2-1);
        //rogi wewnatrz
        suma += sumy[1][2][1][2][a1+1][b1+1];
        suma += sumy[2][1][1][2][a2-1][b1+1];
        suma += sumy[2][1][2][1][a2-1][b2-1];
        suma += sumy[1][2][2][1][a1+1][b2-1];
        //boki
        suma += odczytaj_sume(0,2,2,2,a1,b1+2,a1,b2-2);
        suma += odczytaj_sume(2,0,2,2,a2,b1+2,a2,b2-2);
        suma += odczytaj_sume(2,2,0,2,a1+2,b1,a2-2,b1);
        suma += odczytaj_sume(2,2,2,0,a1+2,b2,a2-2,b1);
        //prawie rogi
        suma += sumy[0][2][1][2][a1][b1+1];
        suma += sumy[0][2][2][1][a1][b2-1];
        suma += sumy[1][2][2][0][a1+1][b2];
        suma += sumy[2][1][2][0][a2-1][b2];
        suma += sumy[2][0][2][1][a2][b2-1];
        suma += sumy[2][0][1][2][a2][b1+1];
        suma += sumy[2][1][0][2][a2-1][b1];
        suma += sumy[1][2][0][2][a1+1][b1];
        //rogi
        suma += sumy[0][2][0][2][a1][b1];
        suma += sumy[0][2][2][0][a1][b2];
        suma += sumy[2][0][2][0][a2][b2];
        suma += sumy[2][0][0][2][a2][b1];
    }
    else{
        if((a2-a1+1)*(b2-b1+1) <= 16){
            int maks=0;
            pair<int,int> ind;
            for(int i=a1;i<=a2;i++){
                for(int j=b1;j<=b2;j++){
                    odwiedzone[i][j] = 0;
                    if(tab[i][j] > maks){
                        maks = tab[i][j];
                        ind = {i,j};
                    }
                }
            }
            licznik = 0;
            dfs(a1,b1,a2,b2,ind.st,ind.nd);
            if(licznik == (a2-a1+1)*(b2-b1+1)){
                return 1;
            }
        }
        else if((a2-a1+1) == 1){
            suma += sumy[0][0][0][2][a1][b1];
            suma += sumy[0][0][2][0][a1][b2];
            suma += sumy[0][0][1][2][a1][b1+1];
            suma += sumy[0][0][2][1][a1][b2-1];
            suma += odczytaj_sume(0,0,2,2,a1,b1+2,a1,b2-2);
        }
        else if((b2-b1+1) == 1){
            suma += sumy[0][2][0][0][a1][b1];
            suma += sumy[2][0][0][0][a2][b1];
            suma += sumy[1][2][0][0][a1+1][b1];
            suma += sumy[2][1][0][0][a2-1][b1];
            suma += odczytaj_sume(2,2,0,0,a1+2,b1,a2-2,b1);
        }
        else if(a2-a1+1 == 2){
            suma += sumy[0][1][0][2][a1][b1];
            suma += sumy[0][1][2][0][a1][b2];
            suma += sumy[1][0][2][0][a2][b2];
            suma += sumy[1][0][0][2][a2][b1];
            suma += sumy[0][1][1][2][a1][b1+1];
            suma += sumy[0][1][2][1][a1][b2-1];
            suma += sumy[1][0][2][1][a2][b2-1];
            suma += sumy[1][0][1][2][a2][b1+1];
            suma += odczytaj_sume(0,1,2,2,a1,b1+2,a1,b2-2);
            suma += odczytaj_sume(1,0,2,2,a2,b1+2,a2,b2-2);
        }
        else if(b2-b1+1 == 2){
            suma += sumy[0][2][0][1][a1][b1];
            suma += sumy[0][2][1][0][a1][b2];
            suma += sumy[2][0][1][0][a2][b2];
            suma += sumy[2][0][0][1][a2][b1];
            suma += sumy[1][2][0][1][a1+1][b1];
            suma += sumy[2][1][0][1][a2-1][b1];
            suma += sumy[1][2][1][0][a1+1][b2];
            suma += sumy[2][1][1][0][a2-1][b2];
            suma += odczytaj_sume(2,2,0,1,a1+2,b1,a2-2,b1);
            suma += odczytaj_sume(2,2,1,0,a1+2,b2,a2-2,b2);
        }
        else if(a2-a1+1 == 3){
            suma += sumy[0][2][0][2][a1][b1];
            suma += sumy[0][2][2][0][a1][b2];
            suma += sumy[2][0][2][0][a2][b2];
            suma += sumy[2][0][0][2][a2][b1];
            suma += sumy[0][2][1][2][a1][b1+1];
            suma += sumy[0][2][2][1][a1][b2-1];
            suma += sumy[2][0][2][1][a2][b2-1];
            suma += sumy[2][0][1][2][a2][b1+1];
            suma += odczytaj_sume(0,2,2,2,a1,b1+2,a1,b2-2);
            suma += odczytaj_sume(2,0,2,2,a2,b1+2,a2,b2-2);
            suma += sumy[1][1][0][2][a1+1][b1];
            suma += sumy[1][1][2][0][a2-1][b2];
            suma += sumy[1][1][1][2][a1+1][b1+1];
            suma += sumy[1][1][2][1][a2-1][b2-1];
            suma += odczytaj_sume(1,1,2,2,a1+1,b1+2,a2-1,b2-2);
        }
        else if(b2-b1+1 == 3){
            suma += sumy[0][2][0][2][a1][b1];
            suma += sumy[0][2][2][0][a1][b2];
            suma += sumy[2][0][2][0][a2][b2];
            suma += sumy[2][0][0][2][a2][b1];
            suma += sumy[1][2][0][2][a1+1][b1];
            suma += sumy[2][1][0][2][a2-1][b1];
            suma += sumy[1][2][2][0][a1+1][b2];
            suma += sumy[2][1][2][0][a2-1][b2];
            suma += odczytaj_sume(2,2,0,2,a1+2,b1,a2-2,b1);
            suma += odczytaj_sume(2,2,2,0,a1+2,b2,a2-2,b2);
            suma += sumy[0][2][1][1][a1][b1+1];
            suma += sumy[2][0][1][1][a2][b2-2];
            suma += sumy[1][2][1][1][a1+1][b1+1];
            suma += sumy[2][1][1][1][a2-1][b2-1];
            suma += odczytaj_sume(2,2,1,1,a1+2,b1+1,a2-2,b2-1);
        }
        else if(a2-a1+1 == 4){
            suma += sumy[0][2][0][2][a1][b1];
            suma += sumy[0][2][2][0][a1][b2];
            suma += sumy[2][0][2][0][a2][b2];
            suma += sumy[2][0][0][2][a2][b1];
            suma += sumy[0][2][1][2][a1][b1+1];
            suma += sumy[0][2][2][1][a1][b2-1];
            suma += sumy[2][0][2][1][a2][b2-1];
            suma += sumy[2][0][1][2][a2][b1+1];
            suma += sumy[1][2][0][2][a1+1][b1];
            suma += sumy[2][1][0][2][a2-1][b1];
            suma += sumy[1][2][2][0][a1+1][b2];
            suma += sumy[2][1][2][0][a2-1][b2];
            suma += odczytaj_sume(0,2,2,2,a1,b1+2,a1,b2-2);
            suma += odczytaj_sume(2,0,2,2,a2,b1+2,a2,b2-2);
            suma += sumy[1][2][1][2][a1+1][b1+1];
            suma += sumy[2][1][1][2][a2-1][b1+1];
            suma += sumy[2][1][2][1][a2-1][b2-1];
            suma += sumy[1][2][2][1][a1+1][b2-1];
            suma += odczytaj_sume(1,2,2,2,a1+1,b1+2,a1+1,b2-2);
            suma += odczytaj_sume(2,1,2,2,a2-1,b1+2,a2-1,b2-2);
        }
        else{
            suma += sumy[0][2][0][2][a1][b1];
            suma += sumy[0][2][2][0][a1][b2];
            suma += sumy[2][0][2][0][a2][b2];
            suma += sumy[2][0][0][2][a2][b1];
            suma += sumy[0][2][1][2][a1][b1+1];
            suma += sumy[0][2][2][1][a1][b2-1];
            suma += sumy[2][0][2][1][a2][b2-1];
            suma += sumy[2][0][1][2][a2][b1+1];
            suma += sumy[1][2][0][2][a1+1][b1];
            suma += sumy[2][1][0][2][a2-1][b1];
            suma += sumy[1][2][2][0][a1+1][b2];
            suma += sumy[2][1][2][0][a2-1][b2];
            suma += odczytaj_sume(2,2,0,2,a1+2,b1,a2-2,b1);
            suma += odczytaj_sume(2,2,2,0,a1+2,b2,a2-2,b2);
            suma += sumy[1][2][1][2][a1+1][b1+1];
            suma += sumy[2][1][1][2][a2-1][b1+1];
            suma += sumy[2][1][2][1][a2-1][b2-1];
            suma += sumy[1][2][2][1][a1+1][b2-1];
            suma += odczytaj_sume(2,2,1,2,a1+2,b1+1,a2-2,b1+1);
            suma += odczytaj_sume(2,2,2,1,a1+2,b2-1,a2-2,b2-1);
        }
    }

    if(suma == 1)
        return 1;
    return 0;
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int n,m;
    cin>>n>>m;

    int x;
    for(int i=1;i<=n;i++){
        tab[i].pb(0);
        for(int j=1;j<=m;j++){
            cin>>x;
            tab[i].pb(x);
        }
    }
    
    for(int a=0;a<3;a++){
        for(int b=0;b<3;b++){
            for(int c=0;c<3;c++){
                for(int d=0;d<3;d++){
                    sumy[a][b][c][d][0].resize(m+1,0);
                    for(int i=1;i<=n;i++){
                        odwiedzone[i].resize(m+1,0);
                        sumy[a][b][c][d][i].resize(m+1,0);
                        for(int j=1;j<=m;j++){
                            if((a==2 && b==2)||(c==2&&d==2)){
                                sumy[a][b][c][d][i][j] = sumy[a][b][c][d][i][j-1] + sumy[a][b][c][d][i-1][j] - sumy[a][b][c][d][i-1][j-1];
                            }
                            if(sprawdz(a,b,c,d,i,i) != 1)
                                sumy[a][b][c][d][i][j]++;
                        }
                    }
                }
            }
        }
    }

    ll wynik = 0;

    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int k=i;k<=n;k++){
                for(int l=j;l<=m;l++){
                    if(czyzjazd(i,j,k,l))
                        wynik++;
                }
            }
        }
    }

    cout<<wynik<<"\n";

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...