답안 #1009509

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1009509 2024-06-27T15:15:51 Z boris_mihov Rectangles (IOI19_rect) C++17
59 / 100
954 ms 1048576 KB
#include "rect.h"
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>
#include <stack>

typedef long long llong;
const int MAXLOG = 12;
const int MAXN = 2500 + 10;
const int INF  = 1e8;

int n, m;
int getLOG[MAXN];
struct SparseMIN
{
    short sparse[MAXN][MAXLOG];
    int vals[MAXN];
    int len;

    void build(int a[], int length)
    {
        len = length;
        for (int i = 1 ; i <= len ; ++i)
        {
            sparse[i][0] = i; 
            vals[i] = a[i];
        }

        for (int lg = 1 ; (1 << lg) <= len ; ++lg)
        {
            for (int i = 1 ; i + (1 << lg) - 1 <= len ; ++i)
            {
                sparse[i][lg] = (vals[sparse[i][lg - 1]] < vals[sparse[i + (1 << lg - 1)][lg - 1]] ? sparse[i][lg - 1] : sparse[i + (1 << lg - 1)][lg - 1]);
            }
        }
    }

    int findMIN(int l, int r)
    {
        int lg = getLOG[r - l + 1];
        return (vals[sparse[l][lg]] < vals[sparse[r - (1 << lg) + 1][lg]] ? vals[sparse[l][lg]] : vals[sparse[r - (1 << lg) + 1][lg]]);
    }
};

struct SparseMAX
{
    short sparse[MAXN][MAXLOG];
    int vals[MAXN];
    int len;

    void build(int a[], int length)
    {
        len = length;
        for (int i = 1 ; i <= len ; ++i)
        {
            sparse[i][0] = i; 
            vals[i] = a[i];
        }

        for (int lg = 1 ; (1 << lg) <= len ; ++lg)
        {
            for (int i = 1 ; i + (1 << lg) - 1 <= len ; ++i)
            {
                sparse[i][lg] = (vals[sparse[i][lg - 1]] > vals[sparse[i + (1 << lg - 1)][lg - 1]] ? sparse[i][lg - 1] : sparse[i + (1 << lg - 1)][lg - 1]);
            }
        }
    }

    int findMAX(int l, int r)
    {
        int lg = getLOG[r - l + 1];
        return (vals[sparse[l][lg]] > vals[sparse[r - (1 << lg) + 1][lg]] ? vals[sparse[l][lg]] : vals[sparse[r - (1 << lg) + 1][lg]]);
    }
};

int a[MAXN][MAXN]; // >
int b[MAXN][MAXN]; // v
int c[MAXN][MAXN]; // <
int d[MAXN][MAXN]; // ^
int t[MAXN][MAXN];
int cpy[MAXN];

SparseMIN sparseRD[MAXN];
SparseMAX sparseRU[MAXN];
SparseMIN sparseCL[MAXN];
SparseMAX sparseCR[MAXN];
std::vector <int> possibleColE[MAXN][MAXN];
std::vector <int> possibleRowE[MAXN][MAXN];

bool isOK(int rowB, int colB, int rowE, int colE)
{
    rowB--; colB--; rowE++; colE++;
    if (sparseRD[rowB].findMIN(colB + 1, colE - 1) < rowE) return false;
    if (sparseRU[rowE].findMAX(colB + 1, colE - 1) > rowB) return false;
    if (sparseCL[colB].findMIN(rowB + 1, rowE - 1) < colE) return false;
    if (sparseCR[colE].findMAX(rowB + 1, rowE - 1) > colB) return false;
    return true;
}

llong count_rectangles(std::vector <std::vector<int>> _a)
{
    n = _a.size(); m = _a[0].size();
    for (int i = 0 ; i < n ; ++i)
    {
        for (int j = 0 ; j < m ; ++j)
        {
            t[i + 1][j + 1] = _a[i][j];
        }
    }

    for (int i = 0 ; i <= n + 1 ; ++i)
    {
        t[i][0] = t[i][m + 1] = INF;
    }

    for (int i = 0 ; i <= m + 1 ; ++i)
    {
        t[0][i] = t[n + 1][i] = INF;
    }

    std::stack <int> st;
    for (int i = 1 ; i <= n ; ++i)
    {
        while (st.size()) st.pop(); st.push(m + 1);
        for (int j = m ; j >= 1 ; --j)
        {
            while (t[i][j] > t[i][st.top()])
            {
                st.pop();
            }

            a[i][j] = st.top();
            st.push(j);
        }

        while (st.size()) st.pop(); st.push(0);
        for (int j = 1 ; j <= m ; ++j)
        {
            while (t[i][j] > t[i][st.top()])
            {
                st.pop();
            }

            c[i][j] = st.top();
            st.push(j);
        }
    }

    for (int i = 1 ; i <= m ; ++i)
    {
        while (st.size()) st.pop(); st.push(n + 1);
        for (int j = n ; j >= 1 ; --j)
        {
            while (t[j][i] > t[st.top()][i])
            {
                st.pop();
            }

            b[j][i] = st.top();
            st.push(j);
        }

        while (st.size()) st.pop(); st.push(0);
        for (int j = 1 ; j <= n ; ++j)
        {
            while (t[j][i] > t[st.top()][i])
            {
                st.pop();
            }

            d[j][i] = st.top();
            st.push(j);
        }
    }

    for (int i = 1 ; i <= std::max(n, m) ; ++i)
    {
        getLOG[i] = getLOG[i - 1];
        if ((1 << getLOG[i] + 1) < i) getLOG[i]++;
    }

    for (int i = 1 ; i <= n ; ++i)
    {
        sparseRD[i].build(b[i], m);
        sparseRU[i].build(d[i], m);
    }

    for (int i = 1 ; i <= m ; ++i)
    {
        for (int j = 1 ; j <= n ; ++j)
        {
            cpy[j] = a[j][i];
        }

        sparseCL[i].build(cpy, n);

        for (int j = 1 ; j <= n ; ++j)
        {
            cpy[j] = c[j][i];
        }

        sparseCR[i].build(cpy, n);
    }

    for (int i = 2 ; i <= n ; ++i)
    {
        for (int j = 2 ; j <= m ; ++j)
        {
            if (d[i][j] < i - 1) possibleRowE[d[i][j] + 1][j].push_back(i - 1);
            if (c[i][j] < j - 1) possibleColE[i][c[i][j] + 1].push_back(j - 1);
        }
    }

    for (int i = 2 ; i <= n ; ++i)
    {
        for (int j = 2 ; j <= m ; ++j)
        {
            if (i < b[i - 1][j] && b[i - 1][j] != n + 1 && (possibleRowE[i][j].empty() || possibleRowE[i][j].back() != b[i - 1][j] - 1)) possibleRowE[i][j].push_back(b[i - 1][j] - 1);
            if (j < a[i][j - 1] && a[i][j - 1] != m + 1 && (possibleColE[i][j].empty() || possibleColE[i][j].back() != a[i][j - 1] - 1)) possibleColE[i][j].push_back(a[i][j - 1] - 1);
        }
    }

    int answer = 0;
    for (int rowB = 2 ; rowB < n ; ++rowB)
    {
        for (int colB = 2 ; colB < m ; ++colB)
        {
            for (const int &rowE : possibleRowE[rowB][colB])
            {
                for (const int &colE : possibleColE[rowB][colB])
                {
                    answer += isOK(rowB, colB, rowE, colE);
                }
            }
        }
    }

    return answer;
}

Compilation message

rect.cpp: In member function 'void SparseMIN::build(int*, int)':
rect.cpp:35:85: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
   35 |                 sparse[i][lg] = (vals[sparse[i][lg - 1]] < vals[sparse[i + (1 << lg - 1)][lg - 1]] ? sparse[i][lg - 1] : sparse[i + (1 << lg - 1)][lg - 1]);
      |                                                                                  ~~~^~~
rect.cpp:35:142: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
   35 |                 sparse[i][lg] = (vals[sparse[i][lg - 1]] < vals[sparse[i + (1 << lg - 1)][lg - 1]] ? sparse[i][lg - 1] : sparse[i + (1 << lg - 1)][lg - 1]);
      |                                                                                                                                           ~~~^~~
rect.cpp: In member function 'void SparseMAX::build(int*, int)':
rect.cpp:66:85: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
   66 |                 sparse[i][lg] = (vals[sparse[i][lg - 1]] > vals[sparse[i + (1 << lg - 1)][lg - 1]] ? sparse[i][lg - 1] : sparse[i + (1 << lg - 1)][lg - 1]);
      |                                                                                  ~~~^~~
rect.cpp:66:142: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
   66 |                 sparse[i][lg] = (vals[sparse[i][lg - 1]] > vals[sparse[i + (1 << lg - 1)][lg - 1]] ? sparse[i][lg - 1] : sparse[i + (1 << lg - 1)][lg - 1]);
      |                                                                                                                                           ~~~^~~
rect.cpp: In function 'llong count_rectangles(std::vector<std::vector<int> >)':
rect.cpp:126:9: warning: this 'while' clause does not guard... [-Wmisleading-indentation]
  126 |         while (st.size()) st.pop(); st.push(m + 1);
      |         ^~~~~
rect.cpp:126:37: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'
  126 |         while (st.size()) st.pop(); st.push(m + 1);
      |                                     ^~
rect.cpp:138:9: warning: this 'while' clause does not guard... [-Wmisleading-indentation]
  138 |         while (st.size()) st.pop(); st.push(0);
      |         ^~~~~
rect.cpp:138:37: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'
  138 |         while (st.size()) st.pop(); st.push(0);
      |                                     ^~
rect.cpp:153:9: warning: this 'while' clause does not guard... [-Wmisleading-indentation]
  153 |         while (st.size()) st.pop(); st.push(n + 1);
      |         ^~~~~
rect.cpp:153:37: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'
  153 |         while (st.size()) st.pop(); st.push(n + 1);
      |                                     ^~
rect.cpp:165:9: warning: this 'while' clause does not guard... [-Wmisleading-indentation]
  165 |         while (st.size()) st.pop(); st.push(0);
      |         ^~~~~
rect.cpp:165:37: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'
  165 |         while (st.size()) st.pop(); st.push(0);
      |                                     ^~
rect.cpp:181:29: warning: suggest parentheses around '+' inside '<<' [-Wparentheses]
  181 |         if ((1 << getLOG[i] + 1) < i) getLOG[i]++;
      |                   ~~~~~~~~~~^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 109 ms 296508 KB Output is correct
2 Correct 102 ms 298084 KB Output is correct
3 Correct 108 ms 297952 KB Output is correct
4 Correct 109 ms 298068 KB Output is correct
5 Correct 108 ms 298064 KB Output is correct
6 Correct 114 ms 298068 KB Output is correct
7 Correct 107 ms 297540 KB Output is correct
8 Correct 110 ms 297296 KB Output is correct
9 Correct 114 ms 298064 KB Output is correct
10 Correct 114 ms 297996 KB Output is correct
11 Correct 109 ms 298120 KB Output is correct
12 Correct 108 ms 298060 KB Output is correct
13 Correct 105 ms 296296 KB Output is correct
14 Correct 114 ms 296784 KB Output is correct
15 Correct 111 ms 296788 KB Output is correct
16 Correct 108 ms 296532 KB Output is correct
17 Correct 109 ms 296276 KB Output is correct
18 Correct 95 ms 296276 KB Output is correct
19 Correct 111 ms 298068 KB Output is correct
20 Correct 107 ms 297556 KB Output is correct
21 Correct 112 ms 296788 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 109 ms 296508 KB Output is correct
2 Correct 102 ms 298084 KB Output is correct
3 Correct 108 ms 297952 KB Output is correct
4 Correct 109 ms 298068 KB Output is correct
5 Correct 108 ms 298064 KB Output is correct
6 Correct 114 ms 298068 KB Output is correct
7 Correct 107 ms 297540 KB Output is correct
8 Correct 110 ms 297296 KB Output is correct
9 Correct 114 ms 298064 KB Output is correct
10 Correct 114 ms 297996 KB Output is correct
11 Correct 109 ms 298120 KB Output is correct
12 Correct 108 ms 298060 KB Output is correct
13 Correct 105 ms 296296 KB Output is correct
14 Correct 114 ms 296784 KB Output is correct
15 Correct 111 ms 296788 KB Output is correct
16 Correct 108 ms 296532 KB Output is correct
17 Correct 109 ms 296276 KB Output is correct
18 Correct 95 ms 296276 KB Output is correct
19 Correct 111 ms 298068 KB Output is correct
20 Correct 107 ms 297556 KB Output is correct
21 Correct 112 ms 296788 KB Output is correct
22 Correct 109 ms 301652 KB Output is correct
23 Correct 113 ms 301904 KB Output is correct
24 Correct 108 ms 301608 KB Output is correct
25 Correct 115 ms 301456 KB Output is correct
26 Correct 118 ms 301476 KB Output is correct
27 Correct 117 ms 301652 KB Output is correct
28 Correct 132 ms 301468 KB Output is correct
29 Correct 108 ms 300232 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 109 ms 296508 KB Output is correct
2 Correct 102 ms 298084 KB Output is correct
3 Correct 108 ms 297952 KB Output is correct
4 Correct 109 ms 298068 KB Output is correct
5 Correct 108 ms 298064 KB Output is correct
6 Correct 114 ms 298068 KB Output is correct
7 Correct 107 ms 297540 KB Output is correct
8 Correct 110 ms 297296 KB Output is correct
9 Correct 114 ms 298064 KB Output is correct
10 Correct 114 ms 297996 KB Output is correct
11 Correct 109 ms 298120 KB Output is correct
12 Correct 108 ms 298060 KB Output is correct
13 Correct 105 ms 296296 KB Output is correct
14 Correct 114 ms 296784 KB Output is correct
15 Correct 111 ms 296788 KB Output is correct
16 Correct 108 ms 296532 KB Output is correct
17 Correct 109 ms 301652 KB Output is correct
18 Correct 113 ms 301904 KB Output is correct
19 Correct 108 ms 301608 KB Output is correct
20 Correct 115 ms 301456 KB Output is correct
21 Correct 118 ms 301476 KB Output is correct
22 Correct 117 ms 301652 KB Output is correct
23 Correct 132 ms 301468 KB Output is correct
24 Correct 108 ms 300232 KB Output is correct
25 Correct 109 ms 296276 KB Output is correct
26 Correct 95 ms 296276 KB Output is correct
27 Correct 111 ms 298068 KB Output is correct
28 Correct 107 ms 297556 KB Output is correct
29 Correct 112 ms 296788 KB Output is correct
30 Correct 116 ms 314708 KB Output is correct
31 Correct 122 ms 314708 KB Output is correct
32 Correct 122 ms 314704 KB Output is correct
33 Correct 120 ms 313168 KB Output is correct
34 Correct 129 ms 313560 KB Output is correct
35 Correct 127 ms 313424 KB Output is correct
36 Correct 123 ms 313384 KB Output is correct
37 Correct 125 ms 313172 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 109 ms 296508 KB Output is correct
2 Correct 102 ms 298084 KB Output is correct
3 Correct 108 ms 297952 KB Output is correct
4 Correct 109 ms 298068 KB Output is correct
5 Correct 108 ms 298064 KB Output is correct
6 Correct 114 ms 298068 KB Output is correct
7 Correct 107 ms 297540 KB Output is correct
8 Correct 110 ms 297296 KB Output is correct
9 Correct 114 ms 298064 KB Output is correct
10 Correct 114 ms 297996 KB Output is correct
11 Correct 109 ms 298120 KB Output is correct
12 Correct 108 ms 298060 KB Output is correct
13 Correct 105 ms 296296 KB Output is correct
14 Correct 114 ms 296784 KB Output is correct
15 Correct 111 ms 296788 KB Output is correct
16 Correct 108 ms 296532 KB Output is correct
17 Correct 109 ms 301652 KB Output is correct
18 Correct 113 ms 301904 KB Output is correct
19 Correct 108 ms 301608 KB Output is correct
20 Correct 115 ms 301456 KB Output is correct
21 Correct 118 ms 301476 KB Output is correct
22 Correct 117 ms 301652 KB Output is correct
23 Correct 132 ms 301468 KB Output is correct
24 Correct 108 ms 300232 KB Output is correct
25 Correct 116 ms 314708 KB Output is correct
26 Correct 122 ms 314708 KB Output is correct
27 Correct 122 ms 314704 KB Output is correct
28 Correct 120 ms 313168 KB Output is correct
29 Correct 129 ms 313560 KB Output is correct
30 Correct 127 ms 313424 KB Output is correct
31 Correct 123 ms 313384 KB Output is correct
32 Correct 125 ms 313172 KB Output is correct
33 Correct 109 ms 296276 KB Output is correct
34 Correct 95 ms 296276 KB Output is correct
35 Correct 111 ms 298068 KB Output is correct
36 Correct 107 ms 297556 KB Output is correct
37 Correct 112 ms 296788 KB Output is correct
38 Correct 217 ms 418224 KB Output is correct
39 Correct 201 ms 410704 KB Output is correct
40 Correct 203 ms 410704 KB Output is correct
41 Correct 954 ms 403032 KB Output is correct
42 Correct 338 ms 430680 KB Output is correct
43 Correct 233 ms 430624 KB Output is correct
44 Correct 335 ms 430932 KB Output is correct
45 Correct 239 ms 422572 KB Output is correct
46 Correct 226 ms 407888 KB Output is correct
47 Correct 235 ms 410448 KB Output is correct
48 Correct 294 ms 415828 KB Output is correct
49 Correct 295 ms 415824 KB Output is correct
50 Correct 203 ms 368724 KB Output is correct
51 Correct 196 ms 361884 KB Output is correct
52 Correct 285 ms 414548 KB Output is correct
53 Correct 281 ms 414804 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 121 ms 338256 KB Output is correct
2 Correct 121 ms 331856 KB Output is correct
3 Correct 142 ms 338000 KB Output is correct
4 Correct 129 ms 296324 KB Output is correct
5 Correct 126 ms 338180 KB Output is correct
6 Correct 126 ms 338104 KB Output is correct
7 Correct 124 ms 338160 KB Output is correct
8 Correct 116 ms 338256 KB Output is correct
9 Correct 120 ms 338004 KB Output is correct
10 Correct 118 ms 337232 KB Output is correct
11 Correct 119 ms 337776 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 109 ms 296276 KB Output is correct
2 Correct 95 ms 296276 KB Output is correct
3 Correct 111 ms 298068 KB Output is correct
4 Correct 107 ms 297556 KB Output is correct
5 Correct 112 ms 296788 KB Output is correct
6 Correct 109 ms 296784 KB Output is correct
7 Correct 699 ms 787308 KB Output is correct
8 Runtime error 847 ms 1048576 KB Execution killed with signal 9
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 109 ms 296508 KB Output is correct
2 Correct 102 ms 298084 KB Output is correct
3 Correct 108 ms 297952 KB Output is correct
4 Correct 109 ms 298068 KB Output is correct
5 Correct 108 ms 298064 KB Output is correct
6 Correct 114 ms 298068 KB Output is correct
7 Correct 107 ms 297540 KB Output is correct
8 Correct 110 ms 297296 KB Output is correct
9 Correct 114 ms 298064 KB Output is correct
10 Correct 114 ms 297996 KB Output is correct
11 Correct 109 ms 298120 KB Output is correct
12 Correct 108 ms 298060 KB Output is correct
13 Correct 105 ms 296296 KB Output is correct
14 Correct 114 ms 296784 KB Output is correct
15 Correct 111 ms 296788 KB Output is correct
16 Correct 108 ms 296532 KB Output is correct
17 Correct 109 ms 301652 KB Output is correct
18 Correct 113 ms 301904 KB Output is correct
19 Correct 108 ms 301608 KB Output is correct
20 Correct 115 ms 301456 KB Output is correct
21 Correct 118 ms 301476 KB Output is correct
22 Correct 117 ms 301652 KB Output is correct
23 Correct 132 ms 301468 KB Output is correct
24 Correct 108 ms 300232 KB Output is correct
25 Correct 116 ms 314708 KB Output is correct
26 Correct 122 ms 314708 KB Output is correct
27 Correct 122 ms 314704 KB Output is correct
28 Correct 120 ms 313168 KB Output is correct
29 Correct 129 ms 313560 KB Output is correct
30 Correct 127 ms 313424 KB Output is correct
31 Correct 123 ms 313384 KB Output is correct
32 Correct 125 ms 313172 KB Output is correct
33 Correct 217 ms 418224 KB Output is correct
34 Correct 201 ms 410704 KB Output is correct
35 Correct 203 ms 410704 KB Output is correct
36 Correct 954 ms 403032 KB Output is correct
37 Correct 338 ms 430680 KB Output is correct
38 Correct 233 ms 430624 KB Output is correct
39 Correct 335 ms 430932 KB Output is correct
40 Correct 239 ms 422572 KB Output is correct
41 Correct 226 ms 407888 KB Output is correct
42 Correct 235 ms 410448 KB Output is correct
43 Correct 294 ms 415828 KB Output is correct
44 Correct 295 ms 415824 KB Output is correct
45 Correct 203 ms 368724 KB Output is correct
46 Correct 196 ms 361884 KB Output is correct
47 Correct 285 ms 414548 KB Output is correct
48 Correct 281 ms 414804 KB Output is correct
49 Correct 121 ms 338256 KB Output is correct
50 Correct 121 ms 331856 KB Output is correct
51 Correct 142 ms 338000 KB Output is correct
52 Correct 129 ms 296324 KB Output is correct
53 Correct 126 ms 338180 KB Output is correct
54 Correct 126 ms 338104 KB Output is correct
55 Correct 124 ms 338160 KB Output is correct
56 Correct 116 ms 338256 KB Output is correct
57 Correct 120 ms 338004 KB Output is correct
58 Correct 118 ms 337232 KB Output is correct
59 Correct 119 ms 337776 KB Output is correct
60 Correct 109 ms 296784 KB Output is correct
61 Correct 699 ms 787308 KB Output is correct
62 Runtime error 847 ms 1048576 KB Execution killed with signal 9
63 Halted 0 ms 0 KB -