Submission #290778

#TimeUsernameProblemLanguageResultExecution timeMemory
290778IgorIRectangles (IOI19_rect)C++17
59 / 100
5145 ms1039068 KiB
#include <bits/stdc++.h>

using namespace std;

const int INF = 88888888;
const int N = 2512;

typedef vector<vector<int> > vvi;
typedef vector<int> vi;

#define all(x) (x).begin(), (x).end()

int le[N][N], ri[N][N], up[N][N], down[N][N];
vector<pair<int, int> > rooted[N][N];

struct query{
    int l, r;
    int x, tm;
};

bool incr(query a, query b)
{
    return a.x < b.x;
}

bool decr(query a, query b)
{
    return a.x > b.x;
}

int fenw[N];

void reset()
{
    for (int i = 0; i < N; i++) fenw[i] = 0;
}

int get(int pos)
{
    int res = 0;
    while (pos >= 0)
    {
        res += fenw[pos];
        pos = (pos & (pos + 1)) - 1;
    }
    return res;
}

void add(int pos)
{
    while (pos < N)
    {
        fenw[pos]++;
        pos |= (pos + 1);
    }
}
long long count_rectangles(vector<vector<int> > a)
{
    int n = a.size(), m = a[0].size();
    for (int i = 0; i < n; i++)
    {
        vector<pair<int, int> > st;
        st.push_back({-1, INF});
        for (int j = 0; j < m; j++)
        {
            while (st.back().second < a[i][j]) st.pop_back();
            le[i][j] = st.back().first;
            st.push_back({j, a[i][j]});
        }
    }
    for (int i = 0; i < n; i++)
    {
        vector<pair<int, int> > st;
        st.push_back({m, INF});
        for (int j = m - 1; j >= 0; j--)
        {
            while (st.back().second < a[i][j]) st.pop_back();
            ri[i][j] = st.back().first;
            st.push_back({j, a[i][j]});
        }
    }
    for (int j = 0; j < m; j++)
    {
        vector<pair<int, int> > st;
        st.push_back({-1, INF});
        for (int i = 0; i < n; i++)
        {
            while (st.back().second < a[i][j]) st.pop_back();
            up[i][j] = st.back().first;
            st.push_back({i, a[i][j]});
        }
    }
    for (int j = 0; j < m; j++)
    {
        vector<pair<int, int> > st;
        st.push_back({n, INF});
        for (int i = n - 1; i >= 0; i--)
        {
            while (st.back().second < a[i][j]) st.pop_back();
            down[i][j] = st.back().first;
            st.push_back({i, a[i][j]});
        }
    }
    for (int i = 1; i + 1 < n; i++)
    {
        for (int j = 1; j + 1 < m; j++)
        {
            {
                int r = ri[i][j - 1] - 1;
                int u0 = up[i + 1][j] + 1;
                int u1 = up[i + 1][r] + 1;
                int d0 = down[i - 1][j] - 1;
                int d1 = down[i - 1][r] - 1;
                rooted[u0][j].push_back({i, r});
                rooted[u1][j].push_back({i, r});
                rooted[i][j].push_back({d0, r});
                rooted[i][j].push_back({d1, r});
            }
            {
                int l = le[i][j + 1] + 1;
                int u0 = up[i + 1][l] + 1;
                int u1 = up[i + 1][j] + 1;
                int d0 = down[i - 1][l] - 1;
                int d1 = down[i - 1][j] - 1;
                rooted[u0][l].push_back({i, j});
                rooted[u1][l].push_back({i, j});
                rooted[i][l].push_back({d0, j});
                rooted[i][l].push_back({d1, j});
            }
        }
    }
    vector<int> res;
    vector<vector<query> > qd(n);
    vector<vector<query> > qu(n);
    vector<vector<query> > qr(m);
    vector<vector<query> > ql(m);
    for (int i = 1; i < n; i++)
    {
        for (int j = 1; j < m; j++)
        {
            sort(all(rooted[i][j]));
            rooted[i][j].resize(unique(all(rooted[i][j])) - rooted[i][j].begin());
            for (auto p : rooted[i][j])
            {
                int i2 = p.first, j2 = p.second;
                if (i <= i2 && j <= j2 && i2 < n - 1 && j2 < m - 1)
                {
                    qd[i - 1].push_back({j, j2, i2, res.size()});
                    qu[i2 + 1].push_back({j, j2, i, res.size()});
                    qr[j - 1].push_back({i, i2, j2, res.size()});
                    ql[j2 + 1].push_back({i, i2, j, res.size()});
                    res.push_back(1);
                }
            }
            rooted[i][j].clear();
        }
    }
    for (int i = 0; i < n; i++)
    {
        sort(all(qd[i]), incr);
        vector<pair<int, int> > p;
        for (int j = 0; j < m; j++) p.push_back({down[i][j], j});
        sort(all(p));
        p.push_back({INF, 0});
        int j = 0;
        for (auto e : p)
        {
            while (j < qd[i].size() && qd[i][j].x < e.first)
            {
                if (get(qd[i][j].r) - get(qd[i][j].l - 1) != 0) res[qd[i][j].tm] = 0;
                j++;
            }
            add(e.second);
        }
        reset();
    }
    for (int i = 0; i < n; i++)
    {
        sort(all(qu[i]), decr);
        vector<pair<int, int> > p;
        for (int j = 0; j < m; j++) p.push_back({up[i][j], j});
        sort(all(p));
        reverse(all(p));
        p.push_back({-INF, 0});
        int j = 0;
        for (auto e : p)
        {
            while (j < qu[i].size() && qu[i][j].x > e.first)
            {
                if (get(qu[i][j].r) - get(qu[i][j].l - 1) != 0) res[qu[i][j].tm] = 0;
                j++;
            }
            add(e.second);
        }
        reset();
    }
    for (int i = 0; i < m; i++)
    {
        sort(all(qr[i]), incr);
        vector<pair<int, int> > p;
        for (int j = 0; j < n; j++) p.push_back({ri[j][i], j});
        sort(all(p));
        p.push_back({INF, 0});
        int j = 0;
        for (auto e : p)
        {
            while (j < qr[i].size() && qr[i][j].x < e.first)
            {
                if (get(qr[i][j].r) - get(qr[i][j].l - 1) != 0) res[qr[i][j].tm] = 0;
                j++;
            }
            add(e.second);
        }
        reset();
    }
    for (int i = 0; i < m; i++)
    {
        sort(all(ql[i]), decr);
        vector<pair<int, int> > p;
        for (int j = 0; j < n; j++) p.push_back({le[j][i], j});
        sort(all(p));
        reverse(all(p));
        p.push_back({-INF, 0});
        int j = 0;
        for (auto e : p)
        {
            while (j < ql[i].size() && ql[i][j].x > e.first)
            {
                if (get(ql[i][j].r) - get(ql[i][j].l - 1) != 0) res[ql[i][j].tm] = 0;
                j++;
            }
            add(e.second);
        }
        reset();
    }
    return accumulate(all(res), 0);
}

Compilation message (stderr)

rect.cpp: In function 'long long int count_rectangles(std::vector<std::vector<int> >)':
rect.cpp:148:61: warning: narrowing conversion of 'res.std::vector<int>::size()' from 'std::vector<int>::size_type' {aka 'long unsigned int'} to 'int' [-Wnarrowing]
  148 |                     qd[i - 1].push_back({j, j2, i2, res.size()});
      |                                                     ~~~~~~~~^~
rect.cpp:149:61: warning: narrowing conversion of 'res.std::vector<int>::size()' from 'std::vector<int>::size_type' {aka 'long unsigned int'} to 'int' [-Wnarrowing]
  149 |                     qu[i2 + 1].push_back({j, j2, i, res.size()});
      |                                                     ~~~~~~~~^~
rect.cpp:150:61: warning: narrowing conversion of 'res.std::vector<int>::size()' from 'std::vector<int>::size_type' {aka 'long unsigned int'} to 'int' [-Wnarrowing]
  150 |                     qr[j - 1].push_back({i, i2, j2, res.size()});
      |                                                     ~~~~~~~~^~
rect.cpp:151:61: warning: narrowing conversion of 'res.std::vector<int>::size()' from 'std::vector<int>::size_type' {aka 'long unsigned int'} to 'int' [-Wnarrowing]
  151 |                     ql[j2 + 1].push_back({i, i2, j, res.size()});
      |                                                     ~~~~~~~~^~
rect.cpp:168:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  168 |             while (j < qd[i].size() && qd[i][j].x < e.first)
      |                    ~~^~~~~~~~~~~~~~
rect.cpp:188:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  188 |             while (j < qu[i].size() && qu[i][j].x > e.first)
      |                    ~~^~~~~~~~~~~~~~
rect.cpp:207:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  207 |             while (j < qr[i].size() && qr[i][j].x < e.first)
      |                    ~~^~~~~~~~~~~~~~
rect.cpp:227:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  227 |             while (j < ql[i].size() && ql[i][j].x > e.first)
      |                    ~~^~~~~~~~~~~~~~
#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...