Submission #926585

#TimeUsernameProblemLanguageResultExecution timeMemory
926585TAhmed33Bridges (APIO19_bridges)C++98
100 / 100
2967 ms9028 KiB
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 25;
const int SZE = 450;
struct DSU {
    int sze[MAXN], par[MAXN];
    stack <array <int, 2>> ops;
    void init (int n) {
        for (int i = 1; i <= n; i++) {
            sze[i] = 1; par[i] = i;
        }
        while (!ops.empty()) ops.pop();
    }
    inline int find (int x) {
        while (par[x] != x) x = par[x];
        return x;
    }
    void merge (int x, int y) {
        x = find(x); y = find(y);
        if (x == y) return;
        if (sze[x] > sze[y]) swap(x, y);
        sze[y] += sze[x]; 
        par[x] = y;
        ops.push({x, y});
    }
    void rollback () {  
        auto g = ops.top();
        ops.pop();
        sze[g[1]] -= sze[g[0]];
        par[g[0]] = g[0];
    }
} cur;
int n, m, q; 
array <int, 3> edges[MAXN], queries[MAXN];
bool vis[MAXN];
int ans[MAXN];
int main () {
    ios::sync_with_stdio(0); cin.tie(0);    
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        cin >> edges[i][0] >> edges[i][1] >> edges[i][2];
    }
    cin >> q;
    for (int i = 1; i <= q; i++) {
        cin >> queries[i][0] >> queries[i][1] >> queries[i][2];
    }
    for (int l = 1; l <= q; l += SZE) {
        int r = min(q, l + SZE - 1);
        cur.init(n); memset(vis, 0, sizeof(vis));
        vector <int> dd;
        vector <int> qq;
        vector <int> zz;
        for (int i = l; i <= r; i++) {
            if (queries[i][0] == 1) {
                vis[queries[i][1]] = 1;
                zz.push_back(queries[i][1]);
            } else qq.push_back(i);
        }
        for (int i = 1; i <= m; i++) {
            if (!vis[i]) {
                dd.push_back(i);
            }
        }
        vector <int> added[r - l + 1];
        for (int i = l; i <= r; i++) {
            if (queries[i][0] == 1) {
                edges[queries[i][1]][2] = queries[i][2];
            } else {
                for (auto j : zz) {
                    if (edges[j][2] >= queries[i][2]) {
                        added[i - l].push_back(j);
                    }
                }
            }
        }
        sort(qq.begin(), qq.end(), [&] (int a, int b) {
            return queries[a][2] > queries[b][2];
        });
        sort(dd.begin(), dd.end(), [&] (int a, int b) {
            return edges[a][2] < edges[b][2];
        });
        for (auto i : qq) {
            while (!dd.empty() && edges[dd.back()][2] >= queries[i][2]) {
                cur.merge(edges[dd.back()][0], edges[dd.back()][1]);
                dd.pop_back();
            }
            int z = cur.ops.size();
            for (auto j : added[i - l]) {
                cur.merge(edges[j][0], edges[j][1]);
            }
            ans[i] = cur.sze[cur.find(queries[i][1])];
            while ((int)cur.ops.size() > z) cur.rollback();
        }
    }
    for (int i = 1; i <= q; i++) {
        if (queries[i][0] == 2) cout << ans[i] << '\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...