제출 #409156

#제출 시각아이디문제언어결과실행 시간메모리
409156idk321Rectangles (IOI19_rect)C++17
13 / 100
363 ms147720 KiB
#include "rect.h"
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

vector<vector<int>> a;
int n, m;

long long count_rectangles(std::vector<std::vector<int> > A) {
    a = A;
    n = a.size();
    m = a[0].size();

    bool allSmall = true;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (a[i][j] > 1) allSmall = false;
        }
    }

    if (allSmall)
    {
        vector<vector<int>> left(n, vector<int>(m));
        vector<vector<int>> down(n, vector<int>(m));
        vector<vector<int>> pref(n + 1, vector<int>(m + 1));
        for (int i = 1; i <= n; i++)
        {
            int sum = 0;
            for (int j = 1; j <= m; j++)
            {
                sum += a[i - 1][j - 1];
                pref[i][j] = pref[i - 1][j] + sum;
            }
        }

        for (int i = 1; i < n - 1; i++)
        {
            for (int j = m - 2; j >= 1; j--)
            {
                if (j == m - 2)
                {
                    left[i][j] = j;
                } else
                {
                    if (a[i][j + 1] == 1)
                    {
                        left[i][j] = j;
                    } else
                    {
                        left[i][j] = left[i][j + 1];
                    }
                }
            }
        }

        for (int j = 1; j < m - 1; j++)
        {
            for (int i = n - 2; i >= 1; i--)
            {
                if (i == n - 2)
                {
                    down[i][j] = i;
                } else
                {
                    if (a[i + 1][j] == 1)
                    {
                        down[i][j] = i;
                    } else
                    {
                        down[i][j] = down[i + 1][j];
                    }
                }
            }
        }

        int res = 0;
        for (int i = 1; i < n - 1; i++)
        {
            for (int j = 1; j < m - 1; j++)
            {
                int i2 = down[i][j];
                int j2 = left[i][j];

                int sum1 = pref[i2 + 1][j2 + 1] - pref[i2 + 1][j] - pref[i][j2 + 1] + pref[i][j];
                int sum2 = pref[i2 + 2][j2 + 2] - pref[i2 + 2][j - 1] - pref[i - 1][j2 + 2] + pref[i - 1][j - 1];
                sum2 -= a[i2 + 1][j2 + 1];
                sum2 -= a[i2 + 1][j - 1];
                sum2 -= a[i - 1][j2 + 1];
                sum2 -= a[i - 1][j - 1];
                if (sum1 == 0 && sum2 == (i2 - i + 1) * 2 + (j2 - j + 1) * 2) res++;
            }
        }

        return res;
    } else
    {
        ll res = 0;


        vector<vector<vector<int>>> goodVer(n, vector<vector<int>>(m));


        for (int j = 0; j < m; j++)
        {
            for (int i = 0; i < n - 2; i++)
            {
                int cmax = max({a[i][j], a[i + 1][j]});
                for (int k = i + 2; k < n; k++)
                {
                    cmax = max(cmax, a[k][j]);
                    if (cmax < a[i][j] && cmax < a[k][j])
                    {
                        goodVer[i][j].push_back(k);
                    }
                }
            }
        }




        vector<vector<vector<int>>> goDown(n, vector<vector<int>>(m, vector<int>(m)));
        for (int i = n - 1; i >= 0; i--)
        {
            for (int j = 0; j < m - 2; j++)
            {
                int cmax = max(a[i][j], a[i][j + 1]);
                for (int k = j + 2; k < m; k++)
                {
                    cmax = max(cmax, a[i][k]);
                    if (cmax < a[i][j] && cmax < a[i][k])
                    {
                        if (i != n - 1) goDown[i][j][k] = goDown[i + 1][j][k] + 1;
                        else goDown[i][j][k] = 1;
                    }
                }
            }
        }



        for (int i = 0; i < n - 1; i++)
        {
            for (int j = 0; j < m; j++)
            {
                deque<int> atHeight;
                for (int k = j + 1; k < m - 1; k++)
                {
                    if (k == j + 1)
                    {
                        for (int x : goodVer[i][k])
                        {
                            atHeight.push_back(x);
                        }
                    } else
                    {
                        auto it = atHeight.begin();
                        auto it2 = goodVer[i][k].begin();

                        while (true)
                        {
                            if (it == atHeight.end()) break;
                            if (it2 == goodVer[i][k].end())
                            {
                                it = atHeight.erase(it);
                            } else
                            {
                                if (*it == *it2)
                                {
                                    it++;
                                    it2++;
                                } else
                                {
                                    if (*it > *it2)
                                    {
                                        it2++;
                                    } else it = atHeight.erase(it);
                                }

                            }
                        }
                    }



                    for (int num : atHeight)
                    {
                        if (num <= i + goDown[i + 1][j][k + 1] + 1) res++;
                    }
                }
            }
        }

        return res;
    }

	return 1;
}

/*
5 5
0 1 1 1 0
1 0 1 0 1
1 0 1 0 1
1 0 1 0 1
0 1 1 1 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...