답안 #467302

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
467302 2021-08-22T12:51:22 Z phathnv Paint (COI20_paint) C++11
48 / 100
765 ms 524292 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[u]) {
        if (s[v].find(p.first) != s[v].end()) {
            auto &q = s[v][p.first];
            if (p.second.size() < q.size())
                swap(p.second, q);
            for (int x : q)
                p.second.push_back(x);
            s[v].erase(p.first);
        }
    }
    for (auto &p : s[v]) {
        assert(s[u].find(p.first) == s[u].end());
        s[u][p.first] = p.second;
    }
    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);
                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) {
                adj[u].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) {
                adj[u].push_back(x);
                adj[x].push_back(u);
            } else {
                s[u][col[x]].push_back(x);
            }
        }
        adj[u] = newAdj;
    } else {
        vector<int> newAdj;
        for (int x : adj[u]) {
            x = FindRoot(x);
            if (x == u)
                continue;
            newAdj.push_back(x);
            if (sz[x] >= BLOCKSIZE)
                s[x][col[u]].push_back(u);
        }
        for (int x : adj[v]) {
            x = FindRoot(x);
            if (x == u)
                continue;
            newAdj.push_back(x);
            if (sz[x] >= BLOCKSIZE)
                s[x][col[u]].push_back(u);
        }
        adj[u] = newAdj;
    }
}

void Color(int u, int c) {
    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);
}

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;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 10 ms 14412 KB Output is correct
2 Correct 10 ms 14412 KB Output is correct
3 Correct 15 ms 14924 KB Output is correct
4 Correct 20 ms 14932 KB Output is correct
5 Correct 233 ms 117540 KB Output is correct
6 Correct 54 ms 17580 KB Output is correct
7 Correct 8 ms 14420 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 88 ms 16780 KB Output is correct
2 Correct 138 ms 19248 KB Output is correct
3 Correct 134 ms 25376 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 565 ms 24888 KB Output is correct
2 Correct 499 ms 25184 KB Output is correct
3 Correct 622 ms 25060 KB Output is correct
4 Correct 306 ms 25192 KB Output is correct
5 Correct 194 ms 24524 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 752 ms 22852 KB Output is correct
2 Runtime error 765 ms 524292 KB Execution killed with signal 9
3 Halted 0 ms 0 KB -