Submission #373876

#TimeUsernameProblemLanguageResultExecution timeMemory
373876ijxjdjdRectangles (IOI19_rect)C++14
100 / 100
4964 ms953156 KiB
#include "rect.h"
#include <bits/stdc++.h>

#define f first
#define s second


const int MAXN = 2500;
using ll = long long;
struct interval {
    int l, r;
    int i;
};
std::vector<interval> right;
std::vector<interval> down;
std::vector<std::pair<int, int>> rightP[MAXN][MAXN];
std::vector<std::pair<int, int>> downP[MAXN][MAXN];
std::vector<std::vector<int>> a;
int N, M;
void setPairs() {
    std::vector<interval> cur;
    for (auto& d : right) {
        if (cur.size() == 0 || d.l != cur.back().l || d.r != cur.back().r || d.i != cur.back().i+1) {
            if (cur.size()) {
                int lst = cur.back().i;
                while (cur.size()) {
                    rightP[cur.back().i][cur.back().l].push_back({lst, cur.back().r});
                    cur.pop_back();
                }
            }
        }
        cur.push_back(d);
    }
    if (cur.size()) {
        int lst = cur.back().i;
        while (cur.size()) {
            rightP[cur.back().i][cur.back().l].push_back({lst, cur.back().r});
            cur.pop_back();
        }
    }
    for (auto& d : down) {
        if (cur.size() == 0 || d.l != cur.back().l || d.r != cur.back().r || d.i != cur.back().i+1) {
            if (cur.size()) {
                int lst = cur.back().i;
                while (cur.size()) {
                    downP[cur.back().l][cur.back().i].push_back({cur.back().r, lst});
                    cur.pop_back();
                }
            }
        }
        cur.push_back(d);
    }
    if (cur.size()) {
        int lst = cur.back().i;
        while (cur.size()) {
            downP[cur.back().l][cur.back().i].push_back({cur.back().r, lst});
            cur.pop_back();
        }
    }
}
void getIntervals() {
//    for (int i = 1; i < N-1; i++) {
//        for (int j = 1; j < M-1; j++) {
//            int mx = 0;
//            for (int k = j; k < M-1; k++) {
//                mx = std::max(mx, a[i][k]);
//                if (a[i][j-1] > mx && a[i][k+1] > mx) {
//                    right[i][j].insert(k);
//                }
//            }
//        }
//    }
//    for (int j = 1; j < M-1; j++) {
//        for (int i = 1; i < N-1; i++) {
//            int mx = 0;
//            for (int k = i; k < N-1; k++) {
//                mx = std::max(mx, a[k][j]);
//                if (a[i-1][j] > mx && a[k+1][j] > mx) {
//                    down[i][j].insert(k);
//                }
//            }
//        }
//    }
    for (int i = 1; i < N-1; i++) {
        std::stack<std::pair<int, int>> st;
        st.push({a[i][0], 0});
        for (int j = 1; j < M; j++) {
            bool eq = false;
            while (st.size() && a[i][j] >= st.top().f) {
                if (st.top().s + 1 <= j-1) {
//                    if (!right[i][st.top().s+1].count(j-1)) {
//                        std::cout << "I inside"<< '\n';
//                    }
                    right.push_back({st.top().s+1, j-1, i});
                }
                eq = (a[i][j] == st.top().f);
                st.pop();
            }
            if (!eq) {
                if (st.size() && st.top().s + 1 <= j-1) {
//                    if (!right[i][st.top().s+1].count(j-1)) {
//                        std::cout << "I out"<< '\n';
//
                    right.push_back({st.top().s+1, j-1, i});
                }
            }
            st.push({a[i][j], j});
        }
    }
    for (int j = 1; j < M-1; j++) {
        std::stack<std::pair<int, int>> st;
        st.push({a[0][j], 0});
        for (int i = 1; i < N; i++) {
            bool eq = false;
            while (st.size() && a[i][j] >= st.top().f) {
                if (st.top().s + 1 <= i-1) {
//                    if (!down[st.top().s+1][j].count(i-1)) {
//                        std::cout << st.top().s+1 << " " << j << " " << i-1 <<'\n';
//                    }
                    down.push_back({st.top().s+1, i-1, j});
                }
                eq = (a[i][j] == st.top().f);
                st.pop();
            }
            if (!eq) {
                if (st.size() && st.top().s + 1 <= i-1) {
//                    if (!down[st.top().s+1][j].count(i-1)) {
//                        std::cout << st.top().s+1 << " " << j << " " << i-1 <<'\n';
//                    }
                    down.push_back({st.top().s+1, i-1, j});
                }
            }
            st.push({a[i][j], i});
        }
    }
    auto comp = [] (const interval& lhs, const interval& rhs) {
        if (lhs.l != rhs.l) {
            return lhs.l < rhs.l;
        }
        else if (rhs.r != lhs.r) {
            return lhs.r < rhs.r;
        }
        else {
            return lhs.i < rhs.i;
        }
    };
    sort(down.begin(), down.end(), comp);
    sort(right.begin(), right.end(), comp);
    setPairs();
}
int fen[MAXN];
void add(int val, int id) {
    for (;id<MAXN;id=(id|(id+1))) {
        fen[id]+=val;
    }
}
int sm(int r) {
    int rs = 0;
    for (;r >= 0; r=(r&(r+1)) - 1) {
        rs += fen[r];
    }
    return rs;
}
int sm(int l, int r) {
    return sm(r) - sm(l-1);
}
long long count_rectangles(std::vector<std::vector<int> > board) {
    a = board;
    N = a.size();
    M = a[0].size();
    if (N <= 2 || M <= 2) {
        return 0;
    }
    getIntervals();
    ll res = 0;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            std::sort(rightP[i][j].begin(), rightP[i][j].end());
            std::sort(downP[i][j].begin(), downP[i][j].end());
            int u = 0;
            for (auto& p : rightP[i][j]) {
                while (u < downP[i][j].size() && downP[i][j][u].f <= p.f) {
                    add(1, downP[i][j][u].s);
                    u++;
                }
                res += sm(p.s, MAXN-1);
//                for (auto& u : downP[i][j]) {
//                    if (u.f <= p.f && u.s >= p.s) {
//                        res++;
//                    }
//                }
            }
//            memset(fen, 0, sizeof(fen));
            while (--u>= 0) {
                add(-1, downP[i][j][u].s);
            }
        }
    }
    return res;
}

Compilation message (stderr)

rect.cpp: In function 'long long int count_rectangles(std::vector<std::vector<int> >)':
rect.cpp:182:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  182 |                 while (u < downP[i][j].size() && downP[i][j][u].f <= p.f) {
      |                        ~~^~~~~~~~~~~~~~~~~~~~
#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...