Submission #199933

# Submission time Handle Problem Language Result Execution time Memory
199933 2020-02-04T07:23:09 Z tri Rectangles (IOI19_rect) C++14
0 / 100
7 ms 888 KB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;

using namespace __gnu_pbds;
typedef tree<
        int,
        null_type,
        less<int>,
        rb_tree_tag,
        tree_order_statistics_node_update>
        ordered_set;

#define pb push_back
#define f first
#define s second

namespace debug {
    const int DEBUG = true;

    template<class T1, class T2>
    void pr(const pair<T1, T2> &x);

    template<class T, size_t SZ>
    void pr(const array<T, SZ> &x);

    template<class T>
    void pr(const vector<T> &x);

    template<class T>
    void pr(const set<T> &x);

    template<class T1, class T2>
    void pr(const map<T1, T2> &x);

    template<class T>
    void pr(const T &x) { if (DEBUG) cout << x; }

    template<class T, class... Ts>
    void pr(const T &first, const Ts &... rest) { pr(first), pr(rest...); }

    template<class T1, class T2>
    void pr(const pair<T1, T2> &x) { pr("{", x.f, ", ", x.s, "}"); }

    template<class T>
    void prIn(const T &x) {
        pr("{");
        bool fst = 1;
        for (auto &a : x) {
            pr(fst ? "" : ", ", a), fst = 0;
        }
        pr("}");
    }

    template<class T, size_t SZ>
    void pr(const array<T, SZ> &x) { prIn(x); }

    template<class T>
    void pr(const vector<T> &x) { prIn(x); }

    template<class T>
    void pr(const set<T> &x) { prIn(x); }

    template<class T1, class T2>
    void pr(const map<T1, T2> &x) { prIn(x); }

    void ps() { pr("\n"), cout << flush; }

    template<class Arg, class... Args>
    void ps(const Arg &first, const Args &... rest) {
        pr(first, " ");
        ps(rest...);
    }
}
using namespace debug;

const int MAXN = 2505;

int N, M;
ll ans = 0;

struct block {
    int l, r;
    int len;

    bool operator<(block o) {
        if (l != o.l) return l < o.l;
        if (r != o.r) return r < o.r;
        return len < o.len;
    }

    bool operator<(pi o) {
        if (l != o.f) return l < o.f;
        return r < o.s;
    }

    bool operator==(pi o) {
        return l == o.f && r == o.s;
    }
};

bool longestFirst(block a, block b) {
    if (a.len != b.len) return a.len > b.len;
    return a < b;
}

vector<pi> findRanges(vi &a) {
    vector<pi> ranges;

    set<int> active;

    vector<pi> pts;
    for (int i = 0; i < a.size(); i++) {
        pts.pb({a[i], i});
    }

    sort(pts.begin(), pts.end());
    reverse(pts.begin(), pts.end());

    for (pi &x :pts) {
        int cLoc = x.s;
        auto it = active.upper_bound(cLoc);
        if (it != active.end()) {
            int above = *it;
            if (cLoc + 1 < above) {
                ranges.pb({cLoc + 1, above - 1});
            }
        }
        if (it != active.begin()) {
            it--;
            int below = *it;

            if (below + 1 < cLoc) {
                ranges.pb({below + 1, cLoc - 1});
            }
        }
        active.insert(cLoc);
    }
    sort(ranges.begin(), ranges.end());
    return ranges;
}

vector<pi> ranges[MAXN];

vector<block> rColumnQ[MAXN];

int mode = 0;

vector<block> matchPrev(vector<block> blocks, vector<pi> ranges, int cRow = -1) {

    vector<block> newBlocks;

    int nBI = 0;
    for (pi cR : ranges) {
        while (nBI < blocks.size() && blocks[nBI] < cR) {
            if (mode == 0) {
                block cBlock = blocks[nBI];
                // end of cBlock (no longer extended)
                rColumnQ[cBlock.r].pb({cRow - cBlock.len, cRow - 1, cBlock.r - cBlock.l + 1});
            }

            nBI++;
        }

        if (nBI < blocks.size() && blocks[nBI] == cR) {
            block cBlock = blocks[nBI];

            newBlocks.pb({cBlock.l, cBlock.r, cBlock.len + 1});

            nBI++;
        } else {
            newBlocks.pb({cR.f, cR.s, 1});
        }
    }

    while (nBI < blocks.size()) {
        if (mode == 0) {
            block cBlock = blocks[nBI];
            // end of cBlock (no longer extended)
            rColumnQ[cBlock.r].pb({cRow - cBlock.len, cRow - 1, cBlock.r - cBlock.l + 1});
        }

        nBI++;
    }

    return newBlocks;
}

vi getColumn(vector<vi> &a, int cI) {
    vi col;
    for (int i = 0; i < N; i++) {
        col.pb(a[i][cI]);
    }
    return col;
}

ll count_rectangles(vector<vi> a) {
    N = a.size();
    M = a[0].size();

    for (int cR = 1; cR < N; cR++) {
        ranges[cR] = findRanges(a[cR]);
    }

    mode = 0;
    vector<block> cBlocks;
    for (int cR = 1; cR <= N; cR++) { // include N to flush all blocks at the end
        cBlocks = matchPrev(cBlocks, ranges[cR], cR);
    }

    cBlocks.clear();
    mode = 1;

    ordered_set osets[MAXN];

    for (int cC = 1; cC < N; cC++) {
        vi cCol = getColumn(a, cC);
        vector<pi> cRanges = findRanges(cCol);

        cBlocks = matchPrev(cBlocks, cRanges);

        sort(cBlocks.begin(), cBlocks.end(), longestFirst);

        int nBI = 0;
        for (block cQ : rColumnQ[cC]) {
            while (nBI < cBlocks.size() && cBlocks[nBI].len >= cQ.len) {
                block cBlock = cBlocks[nBI];
                osets[cBlock.r].insert(cBlock.l);
                nBI++;
            }

            for (int cR = cQ.l; cR <= cQ.r; cR++) {
                ans += osets[cR].size() - osets[cR].order_of_key(cQ.l);
            }
        }
        sort(cBlocks.begin(), cBlocks.end());
    }
    return ans;
}

Compilation message

rect.cpp: In function 'std::vector<std::pair<int, int> > findRanges(vi&)':
rect.cpp:124:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 0; i < a.size(); i++) {
                     ~~^~~~~~~~~~
rect.cpp: In function 'std::vector<block> matchPrev(std::vector<block>, std::vector<std::pair<int, int> >, int)':
rect.cpp:166:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         while (nBI < blocks.size() && blocks[nBI] < cR) {
                ~~~~^~~~~~~~~~~~~~~
rect.cpp:176:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if (nBI < blocks.size() && blocks[nBI] == cR) {
             ~~~~^~~~~~~~~~~~~~~
rect.cpp:187:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     while (nBI < blocks.size()) {
            ~~~~^~~~~~~~~~~~~~~
rect.cpp: In function 'll count_rectangles(std::vector<std::vector<int> >)':
rect.cpp:237:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             while (nBI < cBlocks.size() && cBlocks[nBI].len >= cQ.len) {
                    ~~~~^~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 5 ms 632 KB Output is correct
2 Correct 6 ms 632 KB Output is correct
3 Correct 5 ms 632 KB Output is correct
4 Correct 6 ms 632 KB Output is correct
5 Correct 5 ms 632 KB Output is correct
6 Incorrect 6 ms 632 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 5 ms 632 KB Output is correct
2 Correct 6 ms 632 KB Output is correct
3 Correct 5 ms 632 KB Output is correct
4 Correct 6 ms 632 KB Output is correct
5 Correct 5 ms 632 KB Output is correct
6 Incorrect 6 ms 632 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 5 ms 632 KB Output is correct
2 Correct 6 ms 632 KB Output is correct
3 Correct 5 ms 632 KB Output is correct
4 Correct 6 ms 632 KB Output is correct
5 Correct 5 ms 632 KB Output is correct
6 Incorrect 6 ms 632 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 5 ms 632 KB Output is correct
2 Correct 6 ms 632 KB Output is correct
3 Correct 5 ms 632 KB Output is correct
4 Correct 6 ms 632 KB Output is correct
5 Correct 5 ms 632 KB Output is correct
6 Incorrect 6 ms 632 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 7 ms 888 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 5 ms 632 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 5 ms 632 KB Output is correct
2 Correct 6 ms 632 KB Output is correct
3 Correct 5 ms 632 KB Output is correct
4 Correct 6 ms 632 KB Output is correct
5 Correct 5 ms 632 KB Output is correct
6 Incorrect 6 ms 632 KB Output isn't correct
7 Halted 0 ms 0 KB -