Submission #1352355

#TimeUsernameProblemLanguageResultExecution timeMemory
1352355vjudge1Bridges (APIO19_bridges)C++20
14 / 100
891 ms8040 KiB
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int BLOCK_SIZE = 1000;
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) {
        if (parent[i] == i) return i;
        return find(parent[i]); 
    }
    bool merge(int u, int v) {
        int root_u = find(u);
        int root_v = find(v);
        if (root_u == root_v) return false;
        if (sz[root_u] < sz[root_v]) swap(root_u, root_v);
        
        parent[root_v] = root_u;
        sz[root_u] += sz[root_v];
        history.push_back({root_v, root_u}); // ??????????? ????????
        return true;
    }

    void rollback(int steps) {
        while (steps > 0 && !history.empty()) {
            int v = history.back().first;
            int u = history.back().second;
            history.pop_back();
            sz[u] -= sz[v];
            parent[v] = v;
            steps--;
        }
    }
    
    int get_size(int u) {
        return sz[find(u)];
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n, m;
    if (!(cin >> n >> m)) return 0;

    vector<Edge> edges(m + 1);
    vector<int> current_weight(m + 1);
    for (int i = 1; i <= m; i++) {
        cin >> edges[i].u >> edges[i].v >> edges[i].d;
        edges[i].id = i;
        current_weight[i] = edges[i].d;
    }

    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;
    }

    vector<int> ans(q, -1);
    vector<bool> changed(m + 1, false);
    for (int l = 0; l < q; l += BLOCK_SIZE) {
        int r = min(q - 1, l + BLOCK_SIZE - 1);
        
        vector<Query> ask_queries;
        vector<int> to_change; // ??? ???? ????? ?????????? ??????????? ID

        for (int i = l; i <= r; i++) {
            if (queries[i].type == 1) {
                changed[queries[i].x] = true;
                to_change.push_back(queries[i].x);
            } else {
                ask_queries.push_back(queries[i]);
            }
        }

        vector<Edge> unchanged_edges;
        for (int i = 1; i <= m; i++) {
            if (!changed[i]) {
                unchanged_edges.push_back({edges[i].u, edges[i].v, current_weight[i], i});
            }
        }
        sort(unchanged_edges.begin(), unchanged_edges.end(), [](const Edge& a, const Edge& b) {
            return a.d > b.d;
        });
        sort(ask_queries.begin(), ask_queries.end(), [](const Query& a, const Query& b) {
            return a.y > b.y;
        });

        RollbackDSU dsu(n);
        int edge_ptr = 0;

        for (auto& qry : ask_queries) {
            while (edge_ptr < unchanged_edges.size() && unchanged_edges[edge_ptr].d >= qry.y) {
                dsu.merge(unchanged_edges[edge_ptr].u, unchanged_edges[edge_ptr].v);
                edge_ptr++;
            }

            int rollback_steps = 0;
            vector<int> temp_weights; // ??????????? ??????????? ??????? ??????? ???? ????
            
            for (int id : to_change) {
                changed[id] = false; // ??? ??????? ?????????
            }
            
            for (int i = l; i <= qry.id; i++) {
                if (queries[i].type == 1) {
                    current_weight[queries[i].x] = queries[i].y;
                }
            }

            for (int id : to_change) {
                if (!changed[id]) { // ???? ????? ???? ????? ??????????? ???? ????? ??? 1 ? ???? ????
                    changed[id] = true;
                    if (current_weight[id] >= qry.y) {
                        if (dsu.merge(edges[id].u, edges[id].v)) {
                            rollback_steps++;
                        }
                    }
                }
            }


            ans[qry.id] = dsu.get_size(qry.x);

            dsu.rollback(rollback_steps);
            

            for (int i = l; i <= qry.id; i++) {
                if (queries[i].type == 1) {
                   
                }
            }
            
        }
        

        for (int id : to_change) changed[id] = false;
        for (int i = l; i <= r; i++) {
            if (queries[i].type == 1) {
                current_weight[queries[i].x] = queries[i].y;
            }
        }
    }

    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...