Submission #971255

#TimeUsernameProblemLanguageResultExecution timeMemory
971255CDuongLand of the Rainbow Gold (APIO17_rainbow)C++17
12 / 100
651 ms126964 KiB
#include "rainbow.h"
#include <bits/stdc++.h>
using namespace std;

template<class B, class T>
struct fenwick_tree_2d_sparse_sum{
    vector<B> X;
    vector<vector<array<B, 2>>> Y;
    vector<vector<T>> data;
    fenwick_tree_2d_sparse_sum() {}
    // O(n * log^2(n))
    fenwick_tree_2d_sparse_sum(vector<pair<array<B, 2>, T>> init): X(init.size()){
        sort(init.begin(), init.end());
        for(auto i = 0; i < (int)init.size(); ++ i) X[i] = init[i].first[0];
        sort(X.begin(), X.end());
        X.erase(unique(X.begin(), X.end()), X.end());
        int n = (int)X.size();
        Y.resize(n);
        data.resize(n);
        vector<vector<pair<array<B, 2>, T>>> hold(n);
        for(auto i = 0, x = 0; i < (int)init.size(); ++ i){
            auto [pos, val] = init[i];
            while(X[x] < pos[0]) ++ x;
            hold[x].push_back({{pos[1], pos[0]}, val});
        }
        for(auto x = 1; x <= n; ++ x) if(x + (x & -x) <= n){
            auto &hold0 = hold[x + (x & -x) - 1];
            auto &hold1 = hold[x - 1];
            int size = (int)hold0.size();
            hold0.insert(hold0.end(), hold1.begin(), hold1.end());
        }
        for(auto x = 0; x < n; ++ x){
            auto &Y0 = Y[x];
            auto &hold0 = hold[x];
            auto &data0 = data[x];
            sort(hold0.begin(), hold0.end());
            Y0.resize(hold0.size());
            for(auto j = 0; j < (int)hold0.size(); ++ j) Y0[j] = hold0[j].first;
            Y0.erase(unique(Y0.begin(), Y0.end()), Y0.end());
            data0.resize(Y0.size());
            for(auto j = 0, y = 0; j < (int)hold0.size(); ++ j){
                while(Y0[y] < hold0[j].first) ++ y;
                data0[y] += hold0[j].second;
            }
            int m = (int)data0.size();
            for(auto y = 1; y <= m; ++ y) if(y + (y & -y) <= m) data0[y + (y & -y) - 1] += data0[y - 1];
        }
    }
    // O(log^2(n))
    void update(B _p, B _q, T x){
        int p = lower_bound(X.begin(), X.end(), _p) - X.begin();
        assert(p < (int)X.size() && X[p] == _p);
        for(auto i = p + 1; i <= (int)X.size(); i += i & -i){
            auto &Y0 = Y[i - 1];
            auto &data0 = data[i - 1];
            int q = lower_bound(Y0.begin(), Y0.end(), array{_q, _p}) - Y0.begin();
            assert(q < (int)Y0.size() && Y0[q][0] == _q && Y0[q][1] == _p);
            for(auto j = q + 1; j <= (int)data0.size(); j += j & -j) data0[j - 1] += x;
        }
    }
    // O(log^2(n))
    T prefix(B _xr, B _yr) const{
        int xr = lower_bound(X.begin(), X.end(), _xr) - X.begin();
        T res = 0;
        for(auto i = xr; i > 0; i -= i & -i){
            auto &Y0 = Y[i - 1];
            auto &data0 = data[i - 1];
            int yr = lower_bound(Y0.begin(), Y0.end(), array{_yr, numeric_limits<B>::min()}) - Y0.begin();
            for(auto j = yr; j > 0; j -= j & -j) res += data0[j - 1];
        }
        return res;
    }
    // O(log^2(n))
    T query(B _xl, B _yl, B _xr, B _yr) const{
        if (_xl > _xr) return 0;
        if (_yl > _yr) return 0;
        return prefix(_xr, _yr) - prefix(_xl, _yr) - prefix(_xr, _yl) + prefix(_xl, _yl);
    }
    // O(log^2(n))
    T query(B _x, B _y) const{
        return prefix(_x + 1, _y + 1) - prefix(_x + 1, _y) - prefix(_x, _y + 1) + prefix(_x, _y);
    }
};

template<class T>
void compress(vector<T> &a) {
    sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end()), a.end());
}

vector<pair<array<int, 2>, int>> vertex;
vector<pair<array<int, 2>, int>> col_edge;
vector<pair<array<int, 2>, int>> row_edge;
vector<pair<array<int, 2>, int>> river;
fenwick_tree_2d_sparse_sum<int, int> fw_vertex, fw_col_edge, fw_row_edge, fw_river;


void add_cell(int x, int y) {
    river.push_back({{x, y}, 1});

    vertex.push_back({{x, y}, 1});
    vertex.push_back({{x + 1, y}, 1});
    vertex.push_back({{x, y + 1}, 1});
    vertex.push_back({{x + 1, y + 1}, 1});

    col_edge.push_back({{x, y}, 1});
    col_edge.push_back({{x, y + 1}, 1});

    row_edge.push_back({{x, y}, 1});
    row_edge.push_back({{x + 1, y}, 1});
}

void init(int R, int C, int sr, int sc, int M, char *S) {
    --sr, --sc;
    add_cell(sr, sc);
    for (int i = 0; i < M; ++i) {
        if (S[i] == 'N') --sr;
        if (S[i] == 'S') ++sr;
        if (S[i] == 'E') ++sc;
        if (S[i] == 'W') --sc;
        add_cell(sr, sc);
    }

    compress(vertex);
    compress(col_edge);
    compress(row_edge);
    compress(river);

    fw_vertex = fenwick_tree_2d_sparse_sum(vertex);
    fw_col_edge = fenwick_tree_2d_sparse_sum(col_edge);
    fw_row_edge = fenwick_tree_2d_sparse_sum(row_edge);
    fw_river = fenwick_tree_2d_sparse_sum(river);
}

int colour(int ar, int ac, int br, int bc) {
    --ar, --ac;
    int V = 2 * (br - ar) + 2 * (bc - ac) + fw_vertex.query(ar + 1, ac + 1, br, bc);
    // cout << "V: " << V << endl;
    int E = 2 * (br - ar) + 2 * (bc - ac) + fw_col_edge.query(ar, ac + 1, br, bc) + fw_row_edge.query(ar + 1, ac, br, bc);
    // cout << "E: " << E << endl;
    int R = fw_river.query(ar, ac, br, bc);
    // cout << "R: " << R << endl;
    return E - V + 1 - R;
}

Compilation message (stderr)

rainbow.cpp: In instantiation of 'fenwick_tree_2d_sparse_sum<B, T>::fenwick_tree_2d_sparse_sum(std::vector<std::pair<std::array<B, 2>, T> >) [with B = int; T = int]':
rainbow.cpp:129:50:   required from here
rainbow.cpp:29:17: warning: unused variable 'size' [-Wunused-variable]
   29 |             int size = (int)hold0.size();
      |                 ^~~~
#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...