Submission #1352357

#TimeUsernameProblemLanguageResultExecution timeMemory
1352357vjudge1Bridges (APIO19_bridges)C++20
100 / 100
2754 ms8416 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

struct Edge { int u, v, d, id; };
struct Query { int type, x, y, id; };

struct RollbackDSU {
    vector<int> parent, sz;
    vector<pair<int, int>> history;
    RollbackDSU(int n) {
        parent.resize(n + 1);
        sz.resize(n + 1, 1);
        for (int i = 1; i <= n; i++) parent[i] = i;
    }
    int find(int i) {
        while (parent[i] != i) i = parent[i];
        return i;
    }
    bool merge(int u, int v) {
        int root_u = find(u), root_v = find(v);
        if (root_u == root_v) return false;
        if (sz[root_u] < sz[root_v]) swap(root_u, root_v);
        history.push_back({root_v, root_u});
        parent[root_v] = root_u;
        sz[root_u] += sz[root_v];
        return true;
    }
    void rollback(int target_size) {
        while (history.size() > target_size) {
            int v = history.back().first, u = history.back().second;
            history.pop_back();
            parent[v] = v;
            sz[u] -= sz[v];
        }
    }
};

int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int n, m; cin >> n >> m;
    vector<Edge> edges(m + 1);
    for (int i = 1; i <= m; i++) {
        cin >> edges[i].u >> edges[i].v >> edges[i].d;
        edges[i].id = i;
    }
    int q; cin >> q;
    vector<Query> queries(q);
    for (int i = 0; i < q; i++) {
        cin >> queries[i].type >> queries[i].x >> queries[i].y;
        queries[i].id = i;
    }

    int S = sqrt(q);
    vector<int> ans(q, -1), current_d(m + 1), edge_status(m + 1, 0);
    for (int i = 1; i <= m; i++) current_d[i] = edges[i].d;

    for (int l = 0; l < q; l += S) {
        int r = min(q - 1, l + S - 1);
        vector<Query> ask;
        vector<int> changed_edges, upd_idx;
        
        for (int i = l; i <= r; i++) {
            if (queries[i].type == 1) {
                edge_status[queries[i].x] = 1;
                upd_idx.push_back(i);
            } else ask.push_back(queries[i]);
        }
        
        for (int i = 1; i <= m; i++) 
            if (edge_status[i]) changed_edges.push_back(i);

        vector<Edge> fixed;
        for (int i = 1; i <= m; i++)
            if (!edge_status[i]) fixed.push_back({edges[i].u, edges[i].v, current_d[i], i});

        sort(fixed.begin(), fixed.end(), [](const Edge& a, const Edge& b) { return a.d > b.d; });
        sort(ask.begin(), ask.end(), [](const Query& a, const Query& b) { return a.y > b.y; });

        RollbackDSU dsu(n);
        int ptr = 0;
        for (auto& qry : ask) {
            while (ptr < fixed.size() && fixed[ptr].d >= qry.y) {
                dsu.merge(fixed[ptr].u, fixed[ptr].v);
                ptr++;
            }
            int snapshot = dsu.history.size();
            
         
            for (int i = l; i <= r; i++) {
                if (queries[i].type == 1 && queries[i].id < qry.id) {
                    edges[queries[i].x].d = queries[i].y;
                }
            }
          
            for (int id : changed_edges) {
                if (edges[id].d >= qry.y) dsu.merge(edges[id].u, edges[id].v);
            }
            
            ans[qry.id] = dsu.sz[dsu.find(qry.x)];
            dsu.rollback(snapshot);

           
            for (int i = l; i <= r; i++) {
                if (queries[i].type == 1) edges[queries[i].x].d = current_d[queries[i].x];
            }
        }

        
        for (int i = l; i <= r; i++) {
            if (queries[i].type == 1) current_d[queries[i].x] = queries[i].y;
            edge_status[queries[i].x] = 0;
        }
        for (int id : changed_edges) edges[id].d = current_d[id];
    }

    for (int i = 0; i < q; i++) if (ans[i] != -1) cout << ans[i] << "\n";
    return 0;
}
#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...