제출 #871720

#제출 시각아이디문제언어결과실행 시간메모리
871720sleepntsheep다리 (APIO19_bridges)C++17
0 / 100
3064 ms299192 KiB
#include <iostream>
#include <cassert>
#include <map>
#include <cstring>
#include <vector>
#include <algorithm>
#include <deque>
#include <set>
#include <utility>
#include <array>

using i64 = long long;
using u64 = unsigned long long;
using f64 = double;
using f80 = long double;

using namespace std;
#define ALL(x) x.begin(), x.end()
#define ShinLena cin.tie(nullptr)->sync_with_stdio(false);
#define N 200005
int B = 500;

struct dsu
{
    int p[50001];
    vector<tuple<int, int, int>> rb;
    dsu() { memset(p, -1, sizeof p); }

    int find(int x) { return p[x] < 0 ? x : find(p[x]); }

    inline int unite(int x, int y)
    {
        if ((x = find(x)) == (y = find(y))) return 0;

        if (-p[x] > -p[y]) swap(x, y);
        rb.emplace_back(x, y, p[x]);
        p[y] += p[x];
        p[x] = y;
        return 1;
    }


    inline void rollback()
    {
        assert(rb.size());
        auto [x, y, px] = rb.back();
        p[y] -= px;
        p[x] = px;
        rb.pop_back();
    }
};

vector<tuple<int, int, int>> ask[100004];
int ans[100003];

struct qt
{
    vector<tuple<int, int, int>> t[200005];

    qt() { }

    void add(int x, int y, int eu, int ev, int ew, int v, int l, int r)
    {
        if (r < x || y < l) return;
        if (x <= l && r <= y) { t[v].emplace_back(ew, eu, ev); return; }
        int m = (l+r)/2, vr=v+(m-l+1)*2, vl=v+1;
        add(x, y, eu, ev, ew, vl, l, m), add(x, y, eu, ev, ew, vr, m+1, r);
    }

    set<tuple<int, int, int>> edges;
    struct dsu dsu[401];
    vector<bool> rec[401];

    void push(int w, int u, int v)
    {
        for (int i = 1; i * B <= w; ++i) rec[i].push_back(dsu[i].unite(u, v));
        edges.emplace(w, u, v);
    }

    void pop(int w, int u, int v)
    {
        for (int i = 1; i * B <= w; ++i) 
        {
            auto it = rec[i].back(); rec[i].pop_back();
            if (it) dsu[i].rollback();
        }
        edges.erase({w, u, v});
    }

    void dfs(int v, int l, int r)
    {
        for (auto [w, a, b] : t[v]) push(w, a, b);

        if (l == r)
        {
            for (auto [s, w, qi] : ask[l])
            {
                vector<int> rec;

                int b = w/B+1;
                int st = (b+1) * B - 1;
                struct dsu &d = dsu[b];

                auto it = prev(edges.upper_bound({st, 1e9, 1e9}));
                for (; it != edges.begin() && get<0>(*it) >= w; --it)
                    rec.push_back(d.unite(get<1>(*it), get<2>(*it)));

                ans[qi] = -d.p[d.find(s)];

                for (auto x : rec) if (x) d.rollback();
            }
        }
        else
        {
            int m = (l+r)/2, vl =v+1, vr=v+(m-l+1)*2;
            dfs(vl, l, m);
            dfs(vr, m+1, r);
        }

        for (auto [w, a, b] : t[v]) pop(w, a, b);
    }
} qt;

int n, m, q, ne, nq;
tuple<int, int, int, int> el[100001];

int main()
{
    ShinLena;

    cin >> n >> m;
    {
        vector<int> C;
        for (int i = 1, u, v, w; i <= m; ++i) cin >> u >> v >> w, el[i] = {0, u, v, w}, C.push_back(w);
        cin >> q;
        vector<tuple<int, int, int>> Q(q);
        for (auto &[t, b, r] : Q) cin >> t >> b >> r, C.push_back(r);
        sort(ALL(C));
        C.erase(unique(ALL(C)), C.end());
        for (int i = 1; i <= m; ++i) get<3>(el[i]) = lower_bound(ALL(C), get<3>(el[i])) - C.begin();
        for (auto &[t, b, r] : Q) r = lower_bound(ALL(C), r) - C.begin();

        int i = 1;
        for (auto [t, b, r] : Q)
        {
            if (t == 1)
            {
                auto &[ent, u, v, w] = el[b];
                qt.add(ent, i-1, u, v, w, 0, 0, q);
                ent = i;
                w = r;
            }
            else ask[i].emplace_back(b, r, nq++);
            ++i;
        }
    }

    for (int i = 1; i <= m; ++i)
    {
        auto &[ent, u, v, w] = el[i];
        qt.add(ent, q, u, v, w, 0, 0, q);
    }

    qt.dfs(0, 0, q);

    for (int i = 0; i < nq; ++i) 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...