Submission #872136

#TimeUsernameProblemLanguageResultExecution timeMemory
872136KihihihiBridges (APIO19_bridges)C++17
100 / 100
2968 ms15072 KiB
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <numeric>
#include <ctime>
#include <chrono>
#include <random>
#include <cassert>
#include <vector>
#include <string>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <deque>
#include <bitset>
using namespace std;
mt19937_64 rnd(time(NULL));

const int SQ = 1000;

struct edge
{
    int a, b, w;
};

struct query
{
    int qt, x, y;
};

struct dsu
{
    int n;
    vector<int> p, rk, sz;
    vector<vector<pair<int*, int>>> hist;

    dsu(int in)
    {
        n = in;
        p.resize(n);
        iota(p.begin(), p.end(), 0);
        rk.resize(n);
        sz.resize(n, 1);
    }

    int rt(int v)
    {
        return (p[v] == v ? v : rt(p[v]));
    }

    void unite(int a, int b)
    {
        a = rt(a); b = rt(b);
        hist.push_back({});
        if (a == b)
        {
            return;
        }

        hist.back().reserve(4);
        if (rk[a] < rk[b])
        {
            swap(a, b);
        }
        hist.back().push_back({ &p[b], p[b] });
        p[b] = a;
        hist.back().push_back({ &sz[a], sz[a] });
        sz[a] += sz[b];
        hist.back().push_back({ &sz[b], sz[b] });
        sz[b] = 0;
        hist.back().push_back({ &rk[a], rk[a] });
        rk[a] += (rk[a] == rk[b]);
    }

    void ctrlz()
    {
        while (hist.back().size())
        {
            *hist.back().back().first = hist.back().back().second;
            hist.back().pop_back();
        }
        hist.pop_back();
    }

    int get(int v)
    {
        return sz[rt(v)];
    }
};

void solve()
{
    int n, m;
    vector<edge> e;
    cin >> n >> m;
    e.resize(m);
    for (int i = 0; i < m; i++)
    {
        cin >> e[i].a >> e[i].b >> e[i].w;
        e[i].a--; e[i].b--;
    }

    int q;
    cin >> q;
    for (int qli = 0; qli < q; qli += SQ)
    {
        int qri = qli + SQ - 1;
        qri = min(qri, q - 1);

        vector<query> qr(qri - qli + 1);
        for (int i = 0; i < qr.size(); i++)
        {
            cin >> qr[i].qt >> qr[i].x >> qr[i].y;
            qr[i].x--;
        }
        
        vector<bool> used(m);
        vector<int> ord;
        for (int i = 0; i < qr.size(); i++)
        {
            if (qr[i].qt == 1)
            {
                used[qr[i].x] = true;
            }
            else
            {
                ord.push_back(i);
            }
        }
        sort(ord.begin(), ord.end(),
            [&](int x, int y)
            {
                return qr[x].y > qr[y].y;
            }
        );

        vector<int> eu, notu;
        for (int i = 0; i < m; i++)
        {
            if (used[i])
            {
                eu.push_back(i);
            }
            else
            {
                notu.push_back(i);
            }
        }
        sort(notu.begin(), notu.end(),
            [&](int x, int y)
            {
                return e[x].w < e[y].w;
            }
        );

        dsu kek(n);
        vector<int> ans(qr.size(), -1);
        for (auto& idx : ord)
        {
            auto& [qt, ver, w] = qr[idx];
            while (notu.size() && e[notu.back()].w >= w)
            {
                kek.unite(e[notu.back()].a, e[notu.back()].b);
                notu.pop_back();
            }

            for (auto& i : eu)
            {
                used[i] = false;
            }
            int cnte = 0;
            for (int i = idx - 1; i > -1; i--)
            {
                if (qr[i].qt == 2 || used[qr[i].x])
                {
                    continue;
                }

                if (qr[i].y >= w)
                {
                    cnte++;
                    kek.unite(e[qr[i].x].a, e[qr[i].x].b);
                }
                used[qr[i].x] = true;
            }
            for (auto& i : eu)
            {
                if (used[i])
                {
                    continue;
                }

                if (e[i].w >= w)
                {
                    cnte++;
                    kek.unite(e[i].a, e[i].b);
                }
            }
            ans[idx] = kek.get(ver);

            while (cnte)
            {
                kek.ctrlz();
                cnte--;
            }
        }
        for (int i = 0; i < ans.size(); i++)
        {
            if (ans[i] == -1)
            {
                continue;
            }

            cout << ans[i] << "\n";
        }

        for (int i = 0; i < qr.size(); i++)
        {
            if (qr[i].qt == 1)
            {
                e[qr[i].x].w = qr[i].y;
            }
        }
    }
}

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

    solve();

    return 0;
}

/*

























*/

Compilation message (stderr)

bridges.cpp: In function 'void solve()':
bridges.cpp:113:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  113 |         for (int i = 0; i < qr.size(); i++)
      |                         ~~^~~~~~~~~~~
bridges.cpp:121:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  121 |         for (int i = 0; i < qr.size(); i++)
      |                         ~~^~~~~~~~~~~
bridges.cpp:209:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  209 |         for (int i = 0; i < ans.size(); i++)
      |                         ~~^~~~~~~~~~~~
bridges.cpp:219:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  219 |         for (int i = 0; i < qr.size(); i++)
      |                         ~~^~~~~~~~~~~
#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...