Submission #1215942

#TimeUsernameProblemLanguageResultExecution timeMemory
1215942badge881Collapse (JOI18_collapse)C++20
100 / 100
3116 ms9340 KiB
#include <bits/stdc++.h>
#include "collapse.h"
using namespace std;

vector<int> simulateCollapse(int N, vector<int> T, vector<int> X, vector<int> Y, vector<int> W, vector<int> P)
{
    const int S = 320;

    int C = X.size(), Q = W.size();

    int cnt = 0;
    vector<int> lab(N, -1);
    vector<array<int, 2>> his;
    auto init = [&]()
    {
        fill(lab.begin(), lab.end(), -1);
        cnt = 0;
    };
    auto find = [&](int u) -> int
    {
        while (lab[u] >= 0)
            u = lab[u];
        return u;
    };
    auto unite = [&](int u, int v, bool keep)
    {
        u = find(u), v = find(v);
        if (u == v)
        {
            if (keep)
                his.push_back({-1, -1});
            return;
        }
        if (lab[u] > lab[v])
            swap(u, v);
        if (keep)
            his.push_back({v, lab[v]});
        cnt++;
        lab[u] += lab[v];
        lab[v] = u;
    };
    auto restore = [&]()
    {
        while (his.size())
        {
            auto e = his.back();
            his.pop_back();
            if (~e[0])
            {
                --cnt;
                int &p = lab[e[0]];
                lab[p] -= e[1];
                p = e[1];
            }
        }
    };
    vector<array<int, 2>> comp;
    for (int i = 0; i < C; i++)
    {
        if (X[i] > Y[i])
            swap(X[i], Y[i]);
        comp.push_back({X[i], Y[i]});
    }
    sort(comp.begin(), comp.end());
    comp.erase(unique(comp.begin(), comp.end()), comp.end());
    int M = comp.size();
    vector<int> pos(C);
    for (int i = 0; i < C; i++)
    {
        T[i] ^= 1;
        pos[i] = lower_bound(comp.begin(), comp.end(), array<int, 2>{X[i], Y[i]}) - comp.begin();
    }
    vector<array<int, 3>> queries;
    vector<int> res(Q);
    for (int i = 0; i < Q; i++)
    {
        queries.push_back({P[i], W[i], i});
        res[i] = N;
    }
    sort(queries.begin(), queries.end(), [&](const auto &u, const auto &v)
         { return u[1] < v[1]; });
    vector<bool> tog(M), cur(M), nw(M);
    int ptr = 0;
    for (int i = 0; i < C; i += S)
    {
        int l = i, r = min(C - 1, i + S - 1);
        for (int j = l; j <= r; j++)
            tog[pos[j]] = 1;

        vector<int> add;
        vector<array<int, 2>> cands;
        for (int j = 0; j < M; j++)
            if (!tog[j] && cur[j])
                cands.push_back(comp[j]);
            else if (tog[j])
                add.push_back(j);
        vector<array<int, 3>> ord;
        while (ptr < Q && queries[ptr][1] <= r)
            ord.push_back(queries[ptr++]);

        sort(ord.begin(), ord.end());
        sort(cands.begin(), cands.end(), [&](const auto &u, const auto &v)
             { return u[1] < v[1]; });
        init();
        int k = 0;
        for (auto [x, d, id] : ord)
        {
            while (k < cands.size() && cands[k][1] <= x)
            {
                unite(cands[k][0], cands[k][1], 0);
                k++;
            }
            for (int j = l; j <= d; j++)
                nw[pos[j]] = T[j];
            for (int id : add)
            {
                if (nw[id] && comp[id][1] <= x)
                    unite(comp[id][0], comp[id][1], 1);
                nw[id] = cur[id];
            }
            res[id] -= cnt;
            restore();
        }
        init();
        reverse(ord.begin(), ord.end());
        sort(cands.rbegin(), cands.rend());
        k = 0;
        for (auto [x, d, id] : ord)
        {
            while (k < cands.size() && cands[k][0] > x)
            {
                unite(cands[k][0], cands[k][1], 0);
                k++;
            }
            for (int j = l; j <= d; j++)
                nw[pos[j]] = T[j];
            for (int id : add)
            {
                if (nw[id] && comp[id][0] > x)
                    unite(comp[id][0], comp[id][1], 1);
                nw[id] = cur[id];
            }
            res[id] -= cnt;
            restore();
        }
        for (int j = l; j <= r; j++)
        {
            tog[pos[j]] = 0;
            cur[pos[j]] = T[j];
            nw[pos[j]] = cur[pos[j]];
        }
    }
    return res;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...