Submission #467313

# Submission time Handle Problem Language Result Execution time Memory
467313 2021-08-22T13:35:16 Z phathnv Paint (COI20_paint) C++11
100 / 100
2041 ms 36612 KB
#include <bits/stdc++.h>
using namespace std;

const int N = 200000;
const int BLOCKSIZE = 444;

int m, n, q, curInd;
vector<vector<int>> ind;
vector<int> adj[N];
map<int, vector<int>> s[N];
int root[N], sz[N], col[N];

void MergeMap(int u, int v) {
    for (auto &p : s[v]) {
        for (int x : p.second)
            s[u][p.first].push_back(x);
    }
    s[v].clear();
}

int FindRoot(int u) {
    if (u == root[u])
        return u;
    return root[u] = FindRoot(root[u]);
}

void Merge(int u, int v) {
    u = FindRoot(u);
    v = FindRoot(v);
    if (u == v)
        return;
    assert(col[u] == col[v]);
    if (sz[u] < sz[v])
        swap(u, v);
    MergeMap(u, v);
    root[v] = u;
    if (sz[u] >= BLOCKSIZE) {
        for (int x : adj[v]) {
            x = FindRoot(x);
            if (x == u)
                continue;
            if (sz[x] >= BLOCKSIZE) {
                adj[u].push_back(x);
                if (sz[v] < BLOCKSIZE)
                    adj[x].push_back(u);
            } else {
                s[u][col[x]].push_back(x);
            }
        }
    } else if (sz[u] + sz[v] >= BLOCKSIZE) {
        vector<int> newAdj;
        for (int x : adj[u]) {
            x = FindRoot(x);
            if (x == u)
                continue;
            if (sz[x] >= BLOCKSIZE) {
                newAdj.push_back(x);
                adj[x].push_back(u);
            } else {
                s[u][col[x]].push_back(x);
            }
        }
        for (int x : adj[v]) {
            x = FindRoot(x);
            if (x == u)
                continue;
            if (sz[x] >= BLOCKSIZE) {
                newAdj.push_back(x);
                adj[x].push_back(u);
            } else {
                s[u][col[x]].push_back(x);
            }
        }
        adj[u] = newAdj;
    } else {
        for (int x : adj[v])
            adj[u].push_back(x);
        for (int v : adj[u]) {
            v = FindRoot(v);
            if (sz[v] >= BLOCKSIZE)
                s[v][col[u]].push_back(u);
        }
    }
    sz[u] += sz[v];
    adj[v].clear();
}

void Color(int u, int c) {
    //cerr << "Color" << u << ' ' << c << endl;
    u = FindRoot(u);
    col[u] = c;
    vector<pair<int, int>> shouldMerge, shouldDel;
    for (int v : adj[u]) {
        v = FindRoot(v);
        if (col[u] == col[v])
            shouldMerge.push_back({u, v});
    }
    if (s[u].find(c) != s[u].end()) {
        vector<int> &a = s[u][c];
        for (int v : a) {
            v = FindRoot(v);
            if (col[u] == col[v])
                shouldMerge.push_back({u, v});
        }
        s[u].erase(c);
    }
    for (auto p : shouldMerge)
        Merge(p.first, p.second);
    u = FindRoot(u);
    if (sz[u] < BLOCKSIZE) {
        for (int v : adj[u]) {
            v = FindRoot(v);
            if (sz[v] >= BLOCKSIZE)
                s[v][col[u]].push_back(u);
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> m >> n;
    ind.assign(m, vector<int>(n, 0));
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            ind[i][j] = curInd++;
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++) {
            if (i + 1 < m) {
                adj[ind[i][j]].push_back(ind[i + 1][j]);
                adj[ind[i + 1][j]].push_back(ind[i][j]);
            }
            if (j + 1 < n) {
                adj[ind[i][j]].push_back(ind[i][j + 1]);
                adj[ind[i][j + 1]].push_back(ind[i][j]);
            }
        }
    for (int i = 0; i < m * n; i++) {
        root[i] = i;
        sz[i] = 1;
        col[i] = -1;
    }
    for (int u = 0; u < m * n; u++) {
        int c;
        cin >> c;
        Color(u, c);
    }
    cin >> q;
    while (q--) {
        int x, y, c;
        cin >> x >> y >> c;
        x--, y--;
        Color(ind[x][y], c);
    }
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++)
            cout << col[FindRoot(ind[i][j])] << ' ';
        cout << '\n';
    }
    return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 8 ms 14412 KB Output is correct
2 Correct 9 ms 14412 KB Output is correct
3 Correct 13 ms 14916 KB Output is correct
4 Correct 19 ms 14924 KB Output is correct
5 Correct 22 ms 15564 KB Output is correct
6 Correct 40 ms 15092 KB Output is correct
7 Correct 8 ms 14428 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 77 ms 17204 KB Output is correct
2 Correct 238 ms 21888 KB Output is correct
3 Correct 134 ms 25560 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 164 ms 25680 KB Output is correct
2 Correct 166 ms 26020 KB Output is correct
3 Correct 174 ms 25924 KB Output is correct
4 Correct 325 ms 27748 KB Output is correct
5 Correct 276 ms 26436 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 172 ms 24252 KB Output is correct
2 Correct 453 ms 36612 KB Output is correct
3 Correct 2041 ms 35496 KB Output is correct
4 Correct 1294 ms 35468 KB Output is correct
5 Correct 829 ms 33348 KB Output is correct
6 Correct 269 ms 29816 KB Output is correct
7 Correct 243 ms 29968 KB Output is correct
8 Correct 227 ms 30012 KB Output is correct
9 Correct 826 ms 36104 KB Output is correct