Submission #730995

#TimeUsernameProblemLanguageResultExecution timeMemory
730995danikoynovRectangles (IOI19_rect)C++14
59 / 100
1199 ms1048576 KiB
#include "rect.h"
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;


const int maxn = 2510;

int n, m;
int h[maxn][maxn], lg[maxn];


struct sparse_table
{
    vector < vector < int > > table;

    sparse_table() {};
    void build_sparse_table(vector < int > &values)
    {
        int n = values.size();
        table.resize(lg[n]);
        for (int i = 0; i < lg[n]; i ++)
            table[i].resize(n);

        for (int i = 0; i < n; i ++)
            table[0][i] = values[i];

        for (int j = 1; j < lg[n]; j ++)
            for (int i = 0; i < n - (1 << j); i ++)
            {
                table[j][i] = max(table[j - 1][i],
                                  table[j - 1][i + (1 << (j - 1))]);
            }

    }

    int query(int left, int right)
    {
        int len = lg[right - left + 1] - 1;
        return max(table[len][left], table[len][right - (1 << len) + 1]);
    }
};
sparse_table mrow[maxn], mcol[maxn];

int check_array(int left, int right)
{
    ///cout << left << " : " << right << endl;
    int ans = 0;
    for (int i = left; i <= right; i ++)
        for (int j = i; j <= right; j ++)
        {
            int mx = mrow[1].query(i, j);
            //cout << i << " --- " << j << " -- " << mx << endl;
            if (mx < h[1][i - 1] && mx < h[1][j + 1])
                ans ++;
        }
    return ans;
}

bool check_row(int row, int left, int right)
{
    int mx = mrow[row].query(left, right);
    if (mx < h[row][left - 1] && mx < h[row][right + 1])
        return true;
        return false;
}

bool check_col(int col, int up, int down)
{
    int mx = mcol[col].query(up, down);
    if (mx < h[up - 1][col] && mx < h[down + 1][col])
        return true;
    return false;
}

struct frame
{
    int x1, x2, y1, y2;
    frame(int _x1 = 0, int _x2 = 0, int _y1 = 0, int _y2 = 0)
    {
        x1 = _x1;
        x2 = _x2;
        y1 = _y1;
        y2 = _y2;
    }
};



vector < frame > row_frame, col_frame;
int check(int row, int left, int right)
{
    if (left > right)
        return 0;

        int ans = 0;
        ///cout << row << " :: " << left << " " << right << endl;

    for (int i = row; i < n - 1; i ++)
    {

        if (check_row(i, left, right) == false)
            break;
            bool tf = true;

        for (int j = left; j <= right; j ++)
        {
            if (!check_col(j, row, i))
            {
                tf = false;
                break;
            }
        }

        if (tf)
            ans ++;
    }

    return ans;
}

struct line
{
    int y, t, x1, x2, idx;

    line(int _y, int _t, int _x1, int _x2, int _idx)
    {
        idx = _idx;
        y = _y;
        t = _t;
        x1 = _x1;
        x2 = _x2;
    }
};
bool cmp_y(const line &f1, const line &f2)
{
    if (f1.y == f2.y)
        return f1.t < f2.t;
    return f1.y < f2.y;
}

bool cmp_frame_y2(const frame &f1, const frame &f2)
{
    return f1.y2 < f2.y2;
}
bool cmp_frame_y1(const frame &f1, const frame &f2)
{
    return f1.y1 < f2.y1;
}

vector < line > event[maxn];
int act[maxn * maxn];
ll ways;
void process(frame cur)
{
    for (int i = (int)(col_frame.size()) - 1; i >= 0; i --)
    {
        if (col_frame[i].y2 < cur.y2)
        break;
        if (!act[i])
            continue;

        if (col_frame[i].x1 >= cur.x1 && col_frame[i].x2 <= cur.x2)
            ways ++;
    }
}

vector < frame > row_cell[maxn][maxn], col_cell[maxn][maxn];
long long count_rectangles(vector<vector<int> > a)
{
    n = a.size();
    m = a[0].size();
    for (int i = 1; i <= max(n, m); i ++)
        lg[i] = lg[i / 2] + 1;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < m; j ++)
            h[i][j] = a[i][j];

    for (int i = 0; i < n; i ++)
    {
        ///mrow[i].build_sparse_table(a[i]);
        vector < int > values;
        for (int j = 0; j < m; j ++)
            values.push_back(a[i][j]);
        mrow[i].build_sparse_table(values);
    }
    for (int j = 0; j < m; j ++)
    {
        vector < int > values;
        for (int i = 0; i < n; i ++)
            values.push_back(a[i][j]);
        mcol[j].build_sparse_table(values);
    }


    if (n == 3)
    {
        int ans = 0, len = 0;
        for (int j = 1; j < m - 1; j ++)
        {
            ///cout << j << " :: " << len << endl;
            if (h[1][j] < h[0][j] && h[1][j] < h[2][j])
                len ++;
            else
            {
                if (len > 0)
                    ans += check_array(j - len, j - 1);
                len = 0;
            }
        }
        if (len > 0)
            ans += check_array(m - len - 1, m - 2);

        return ans;
    }


    vector < frame > last_row;

    int ans = 0;
    for (int row = 1; row < n - 1; row ++)
    {
        set < pair < int, int > > st;
        for (int left_col = 0; left_col < m; left_col ++)
        {
            int right_col = left_col + 1;
            while(right_col < m && h[row][left_col] > h[row][right_col])
                right_col ++;
            ///cout << "here " << row << " " << left_col << " " << right_col << endl;
            if (right_col != m && left_col + 1 < right_col)
            {
            ///cout << h[row][left_col] << " " << h[row][right_col] << endl;
                st.insert({left_col + 1, right_col - 1});
            }
        }

        for (int right_col = m - 1; right_col > 0; right_col --)
        {
            int left_col = right_col - 1;
            while(left_col >= 0 && h[row][right_col] > h[row][left_col])
                left_col --;
                ///cout << row << " :: " << left_col << " :: " << right_col << endl;
            if (left_col >= 0 && h[row][right_col] < h[row][left_col] &&
                left_col + 1 < right_col)
            {
                //cout << "row " << row << " " << left_col + 1 << " :: " << right_col - 1 << endl;
                st.insert({left_col + 1, right_col - 1});
            }
        }

        vector < frame > new_row;
        for (int i = 0; i < last_row.size(); i ++)
        {
            pair < int, int > cur = make_pair(last_row[i].y1, last_row[i].y2);
            if (st.find(cur) == st.end())
            {
                row_frame.push_back(last_row[i]);
            }
            else
            {
                last_row[i].x2 ++;
                new_row.push_back(last_row[i]);
                st.erase(cur);
            }
        }

        for (pair < int, int > cur : st)
        {
            new_row.push_back(frame(row, row, cur.first, cur.second));
        }

        last_row = new_row;
    }
    for (frame cur : last_row)
        row_frame.push_back(cur);


    vector < frame > last_col;


    for (int col = 1; col < m - 1; col ++)
    {
        set < pair < int, int > > st;
        for (int left_row = 0; left_row < n; left_row ++)
        {
            int right_row = left_row + 1;
            while(right_row < n && h[left_row][col] > h[right_row][col])
                right_row ++;
            ///cout << "here " << row << " " << left_col << " " << right_col << endl;
            if (right_row != n && left_row + 1 < right_row)
            {
            ///cout << h[row][left_col] << " " << h[row][right_col] << endl;
                st.insert({left_row + 1, right_row - 1});
            }
        }

        for (int right_row = n - 1; right_row > 0; right_row --)
        {
            int left_row = right_row - 1;
            while(left_row >= 0 && h[right_row][col] > h[left_row][col])
                left_row --;
                ///cout << row << " :: " << left_col << " :: " << right_col << endl;
            if (left_row >= 0 && h[right_row][col] < h[left_row][col] &&
                left_row + 1 < right_row)
            {
                //cout << "row " << row << " " << left_col + 1 << " :: " << right_col - 1 << endl;
                st.insert({left_row + 1, right_row - 1});
            }
        }

        vector < frame > new_col;
        for (int i = 0; i < last_col.size(); i ++)
        {
            pair < int, int > cur = make_pair(last_col[i].x1, last_col[i].x2);
            if (st.find(cur) == st.end())
            {
                col_frame.push_back(last_col[i]);
            }
            else
            {
                last_col[i].y2 ++;
                new_col.push_back(last_col[i]);
                st.erase(cur);
            }
        }

        for (pair < int, int > cur : st)
        {
            new_col.push_back(frame(cur.first, cur.second, col, col));
        }

        last_col = new_col;
    }
    for (frame cur : last_col)
        col_frame.push_back(cur);

        /**for (frame cur : last_col)
        {
            cout << "frame " << cur.x1 << " " << cur.x2 << " " << cur.y1 << " " << cur.y2 << endl;
        }*/

    for (frame cur : row_frame)
    {
        for (int x = cur.x1; x <= cur.x2; x ++)
        {
            row_cell[x][cur.y2].push_back(cur);
        }
    }

    for (frame cur : col_frame)
    {
        for (int y = cur.y1; y <= cur.y2; y ++)
        {
            col_cell[cur.x2][y].push_back(cur);
        }
    }


    for (int i = 0; i < n; i ++)
    {
        for (int j = 0; j < m; j ++)
        {
                for (frame row : row_cell[i][j])
        for (frame col : col_cell[i][j])
    {
        bool tf = false;
        if (col.x1 >= row.x1 && col.x2 <= row.x2 &&
            row.y1 >= col.y1 && row.y2 <= col.y2)
                tf = true;

            if (tf)
            {

                ans ++;
            }
    }
        }
    }
    return ans;
}

Compilation message (stderr)

rect.cpp: In function 'bool check_row(int, int, int)':
rect.cpp:64:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
   64 |     if (mx < h[row][left - 1] && mx < h[row][right + 1])
      |     ^~
rect.cpp:66:9: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
   66 |         return false;
      |         ^~~~~~
rect.cpp: In function 'int check(int, int, int)':
rect.cpp:94:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
   94 |     if (left > right)
      |     ^~
rect.cpp:97:9: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
   97 |         int ans = 0;
      |         ^~~
rect.cpp:103:9: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
  103 |         if (check_row(i, left, right) == false)
      |         ^~
rect.cpp:105:13: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
  105 |             bool tf = true;
      |             ^~~~
rect.cpp: In function 'long long int count_rectangles(std::vector<std::vector<int> >)':
rect.cpp:253:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<frame>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  253 |         for (int i = 0; i < last_row.size(); i ++)
      |                         ~~^~~~~~~~~~~~~~~~~
rect.cpp:313:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<frame>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  313 |         for (int i = 0; i < last_col.size(); i ++)
      |                         ~~^~~~~~~~~~~~~~~~~
#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...