Submission #698882

#TimeUsernameProblemLanguageResultExecution timeMemory
698882finn__Bridges (APIO19_bridges)C++17
59 / 100
3048 ms7280 KiB
#include <bits/stdc++.h>
using namespace std;

#pragma GCC optimize("O3")
#pragma GCC target("avx2")

struct Edge
{
    unsigned u, v, w;

    bool operator<(Edge const &e) const { return w > e.w; }
};

struct Query
{
    unsigned t, u, w, i;

    bool operator<(Query const &q) const { return w > q.w; }
};

struct DSU
{
    vector<int64_t> p, s;
    stack<int64_t> operations;

    DSU(size_t n) { p = vector<int64_t>(n, -1), s = vector<int64_t>(n, 1); }

    int64_t find(int64_t u)
    {
        while (p[u] >= 0)
            u = p[u];
        return u;
    }

    void unite(int64_t u, int64_t v)
    {
        u = find(u), v = find(v);
        if (u == v)
            return;
        if (s[u] < s[v])
            swap(u, v);
        operations.push(v);
        s[u] += s[v];
        p[v] = u;
    }

    int64_t component_size(int64_t u) { return s[find(u)]; }

    void rollback(size_t n)
    {
        while (n--)
        {
            s[p[operations.top()]] -= s[operations.top()];
            p[operations.top()] = -1;
            operations.pop();
        }
    }
};

int main()
{
    size_t n, m;
    cin >> n >> m;

    vector<Edge> e(m);

    for (size_t i = 0; i < m; i++)
    {
        cin >> e[i].u >> e[i].v >> e[i].w;
        e[i].u--, e[i].v--;
    }

    size_t q;
    cin >> q;
    size_t const k = 13 * sqrt(q) / 10;
    vector<Query> queries(q);
    for (size_t i = 0; i < q; i++)
    {
        cin >> queries[i].t >> queries[i].u >> queries[i].w;
        queries[i].u--;
        queries[i].i = i;
    }

    vector<unsigned> ans(q, 0);

    for (size_t i = 0; i < q; i += k)
    {
        DSU y(n);
        vector<unsigned> changed;
        vector<Edge> unchanged;
        vector<vector<unsigned>> join(k);
        vector<Query> todo;
        vector<bool> is_changed(m);

        for (size_t j = i; j < min(q, i + k); j++)
        {
            if (queries[j].t == 1)
                changed.push_back(queries[j].u), is_changed[queries[j].u] = 1;
            else
                todo.push_back(queries[j]);
        }

        sort(changed.begin(), changed.end());
        changed.resize(unique(changed.begin(), changed.end()) - changed.begin());

        for (size_t j = 0; j < m; j++)
            if (!is_changed[j])
                unchanged.push_back(e[j]);

        for (size_t j = i; j < min(i + k, q); j++)
        {
            if (queries[j].t == 1)
                e[queries[j].u].w = queries[j].w;
            else
            {
                for (unsigned const &h : changed)
                    if (e[h].w >= queries[j].w)
                        join[j - i].push_back(h);
            }
        }

        sort(unchanged.begin(), unchanged.end());
        sort(todo.begin(), todo.end());
        auto it = unchanged.begin();

        for (Query const &x : todo)
        {
            while (it != unchanged.end() && it->w >= x.w)
                y.unite(it->u, it->v), it++;

            size_t s = y.operations.size();
            for (unsigned const &j : join[x.i - i])
                y.unite(e[j].u, e[j].v);

            ans[x.i] = y.component_size(x.u);
            y.rollback(y.operations.size() - s);
        }
    }

    for (unsigned const &x : ans)
        if (x)
            cout << x << '\n';
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...