Submission #274224

# Submission time Handle Problem Language Result Execution time Memory
274224 2020-08-19T10:06:34 Z ne4eHbKa Rectangles (IOI19_rect) C++17
10 / 100
899 ms 384680 KB
#include "rect.h"
#include <bits/stdc++.h>
using namespace std;

#define ft first
#define sd second
#define _ <<' '<<

void* MEM = malloc(800 << 20);

void* operator new(const size_t f) {
    void* res = MEM;
    MEM += f;
    return res;
}

void operator delete(void*) {}

//#pragma GCC optimize("Ofast,O3")

namespace S {

//#include <ext/pb_ds/assoc_container.hpp>

//typedef __gnu_pbds::cc_hash_table<int, int> ht;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vv;
typedef pair<int, int> pii;

const int N = 2505;

int n, m;
list<short> l[N][N], u[N][N];
int p[N], length[N], la[N];
list<pii> fl[N], cl, fu, cu;
bool mk[N];
int c[2 * N], cn, xn, yn, rc[2 * N];
pii x[N], y[N];
int f[N], fn;

int fw[2 * N], fmax, nx[N + N], pr[N + N];
inline void finit(const int n) { fmax = n; memset(fw, 0, n + 1 << 2); }
inline void fadd(int i) { for(i = fmax - i; i <= fmax; i = nx[i]) fw[i]++; }
inline int fget(int i) { int v{}; for(i = fmax - i; i; i = pr[i]) v += fw[i]; return v; }

ll solve() {
    for(int i = 0; i < N + N; ++i) nx[i] = i + (i & -i), pr[i] = i - (i & -i);
    ll ans = 0;
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            swap(cl, fl[j]);
            auto it = cl.begin();
            for(const int &t : l[i][j]) {
                for(; it != cl.end() && it->ft < t; ++it);
                fl[j].push_back({t, 1 + (it != cl.end() ? it->sd : 0)});
            }
            cl.clear();
            swap(cu, fu);
            it = cu.begin();
            for(const int &t : u[i][j]) {
                for(; it != cu.end() && it->ft < t; ++it);
                fu.push_back({t, 1 + (it != cu.end() ? it->sd : 0)});
            }
            cu.clear();
            const auto &a = fl[j], &b = fu;
            if(a.size() * b.size() < 5) {
                for(const auto &i : a)
                    for(const auto &j : b)
                        ans += i.ft <= j.sd && j.ft <= i.sd;
                continue;
            }
            cn = 0;
            for(const auto &i : a) c[cn++] = i.ft;
            for(const auto &i : b) c[cn++] = i.sd;
            sort(c, c + cn);
            cn = unique(c, c + cn) - c;
            xn = yn = 0;
            finit(cn);
            for(int i = 0; i < cn; ++i) rc[c[i]] = i;
            for(const auto &i : a) x[xn++] = {i.sd, rc[i.ft]};
            for(const auto &i : b) y[yn++] = {i.ft, rc[i.sd]};
            sort(x, x + xn, [] (const pii &a, const pii &b) {return a.ft < b.ft;});
            for(int i = 0, it = 0; i < xn; ++i) {
                for(; it < yn && y[it].ft <= x[i].ft; ++it)
                    fadd(y[it].sd);
                ans += fget(x[i].sd);
            }
        }
        fu.clear();
    }
    return ans;
}

int last(int i) {
    return la[i] == i ? i : la[i] = last(la[i]);
}

void unite(int i, int j) {
    i = last(i), j = last(j);
    length[j] += length[i];
    la[i] = j;
}

}

S::ll count_rectangles(S::vv a) {
    using namespace S;
    n = a.size();
    m = a[0].size();
    for(int i = 0; i < n; ++i) {
        iota(p, p + m, 0);
        iota(la, la + m, 0);
        memset(mk, 0, m);
        sort(p, p + m, [&] (const int &fi, const int &se) {return a[i][fi] < a[i][se];});
        for(int t = 0; t < m; ) {
            int v = a[i][p[t]];
            fn = 0;
            for(; t < m && a[i][p[t]] == v; ++t) {
                int j = p[t];
                mk[j] = true;
                length[j] = 1;
                f[fn++] = j;
                if(j + 1 < m && mk[j + 1]) unite(j, j + 1);
                if(j && mk[j - 1]) unite(j - 1, j);
            }
            for(int it = 0; it < fn; ++it) mk[f[it] = last(f[it])] = false;
            for(int it = 0; it < fn; ++it) {
                int j = f[it];
                if(mk[j]) continue;
                mk[j] = true;
                if(i == 0 || i == n - 1) continue;
                if(j == m - 1 || length[j] == j + 1) continue;
                l[i][j].push_back(length[j]);
            }
        }
    }
    for(int j = 0; j < m; ++j) {
        iota(p, p + n, 0);
        iota(la, la + n, 0);
        memset(mk, 0, n);
        sort(p, p + n, [&] (const int &fi, const int &se) {return a[fi][j] < a[se][j];});
        for(int t = 0; t < n; ) {
            int v = a[p[t]][j];
            fn = 0;
            for(; t < n && a[p[t]][j] == v; ++t) {
                int i = p[t];
                mk[i] = true;
                length[i] = 1;
                f[fn++] = i;
                if(i + 1 < n && mk[i + 1]) unite(i, i + 1);
                if(i && mk[i - 1]) unite(i - 1, i);
            }
            for(int it = 0; it < fn; ++it) mk[f[it] = last(f[it])] = false;
            for(int it = 0; it < fn; ++it) {
                int i = f[it];
                if(mk[i]) continue;
                mk[i] = true;
                if(j == 0 || j == m - 1) continue;
                if(i == n - 1 || length[i] == i + 1) continue;
                u[i][j].push_back(length[i]);
            }
        }
    }
    return solve();
}

#undef ft
#undef sd
#undef _

Compilation message

rect.cpp: In function 'void* operator new(size_t)':
rect.cpp:13:9: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]
   13 |     MEM += f;
      |     ~~~~^~~~
rect.cpp: In function 'void S::finit(int)':
rect.cpp:43:60: warning: suggest parentheses around '+' inside '<<' [-Wparentheses]
   43 | inline void finit(const int n) { fmax = n; memset(fw, 0, n + 1 << 2); }
      |                                                          ~~^~~
# Verdict Execution time Memory Grader output
1 Correct 199 ms 295124 KB Output is correct
2 Correct 199 ms 295288 KB Output is correct
3 Correct 196 ms 295268 KB Output is correct
4 Correct 200 ms 295288 KB Output is correct
5 Correct 199 ms 295164 KB Output is correct
6 Incorrect 202 ms 295288 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 199 ms 295124 KB Output is correct
2 Correct 199 ms 295288 KB Output is correct
3 Correct 196 ms 295268 KB Output is correct
4 Correct 200 ms 295288 KB Output is correct
5 Correct 199 ms 295164 KB Output is correct
6 Incorrect 202 ms 295288 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 199 ms 295124 KB Output is correct
2 Correct 199 ms 295288 KB Output is correct
3 Correct 196 ms 295268 KB Output is correct
4 Correct 200 ms 295288 KB Output is correct
5 Correct 199 ms 295164 KB Output is correct
6 Incorrect 202 ms 295288 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 199 ms 295124 KB Output is correct
2 Correct 199 ms 295288 KB Output is correct
3 Correct 196 ms 295268 KB Output is correct
4 Correct 200 ms 295288 KB Output is correct
5 Correct 199 ms 295164 KB Output is correct
6 Incorrect 202 ms 295288 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 210 ms 295632 KB Output is correct
2 Correct 229 ms 295544 KB Output is correct
3 Correct 232 ms 295368 KB Output is correct
4 Correct 236 ms 295136 KB Output is correct
5 Correct 197 ms 295376 KB Output is correct
6 Correct 201 ms 295460 KB Output is correct
7 Correct 233 ms 295424 KB Output is correct
8 Correct 212 ms 295544 KB Output is correct
9 Correct 202 ms 295420 KB Output is correct
10 Correct 239 ms 295160 KB Output is correct
11 Correct 197 ms 295160 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 199 ms 295160 KB Output is correct
2 Incorrect 899 ms 384680 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 199 ms 295124 KB Output is correct
2 Correct 199 ms 295288 KB Output is correct
3 Correct 196 ms 295268 KB Output is correct
4 Correct 200 ms 295288 KB Output is correct
5 Correct 199 ms 295164 KB Output is correct
6 Incorrect 202 ms 295288 KB Output isn't correct
7 Halted 0 ms 0 KB -