Submission #529301

#TimeUsernameProblemLanguageResultExecution timeMemory
529301dutinmeowBridges (APIO19_bridges)C++17
Compilation error
0 ms0 KiB
#include <bits/stdc++.h>
using namespace std;

struct RollbackUnionFind {
    vector<int> par, siz;
	stack<int> rev;

    RollbackUnionFind() = default;

    RollbackUnionFind(int n) { init(n); }

    void init(int n) {
        par.resize(n);
        siz.resize(n);
        iota(par.begin(), par.end(), 0);
        fill(siz.begin(), siz.end(), 1);
    }

    int find(int u) {
        while (u != par[u])
			u = par[u];
		return u;
    }

    bool merge(int u, int v) {
        u = find(u), v = find(v);
        if (u == v)
            return false;
        if (siz[u] > siz[v]) {
            par[v] = u;
            siz[u] += siz[v];
			rev.push(v);
        } else {
            par[u] = v;
            siz[v] += siz[u];
			rev.push(u);
        }
        return true;
    }

    int size(int u) { return siz[find(u)]; }

	void rollback() {
		int u = rev.top(); rev.pop();
		siz[par[u]] -= siz[u];
		par[u] = u;
	}

	void rollback(size_t s) {
		while (rev.size() > s)
			rollback();
	}
};

int main() {
	int N, M, Q;
	cin >> N >> M;
	struct edge { int u, v, w; };
	vector<edge> E; E.reserve(M);
	for (int i = 0; i < M; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		E.emplace_back(u - 1, v - 1, w);
	}
	cin >> Q;
	struct oper { int t, a, b; };
	vector<oper> Z; Z.reserve(Q);
	for (int i = 0; i < Q; i++) {
		int t, a, b;
		cin >> t >> a >> b;
		Z.emplace_back(t, a - 1, b);
	}

	/*
	cout << N << ' ' << M << '\n';
	for (auto [u, v, w] : E)
		cout << "edge " << u << ' ' << v << ' ' << w << '\n';
	cout << Q << '\n';
	for (auto [t, a, b] : Z)
		cout << "oper " << t << ' ' << a << ' ' << b << '\n';
	*/

	RollbackUnionFind rdsu;
	vector<int> ans(Q);

	const int BLOCK_SIZE = 800;
	for (int q = 0; q < Q; q += BLOCK_SIZE) {
		int ql = q, qr = min(Q, q + BLOCK_SIZE);
		
		vector<bool> B(M, false);
		vector<int> C, D, Y;
		vector<vector<int>> J(qr - ql);
		// B = edge is changed
		// C = operation indicies of changed edges
		// D = unchanged edges
		// Y = operation indicies of queried nodes
		// J = changed indicies to be merged
		for (int i = ql; i < qr; i++) {
			auto [t, a, b] = Z[i];
			if (t == 1) {
				B[a] = true;
				C.push_back(i);
			} else if (t == 2) {
				Y.push_back(i);
			}
		}
		for (int i = 0; i < M; i++) 
			if (!B[i])
				D.push_back(i);
		for (int i = ql; i < qr; i++) {
			auto [t, a, b] = Z[i];
			if (t == 1) {
				E[a].w = b;
			} else if (t == 2) {
				for (int c : C)
					if (E[Z[c].a].w >= b)
						J[i - ql].push_back(c);
			}
		}

		sort(D.begin(), D.end(), [&E](const int i, const int j) { return E[i].w > E[j].w; });
		sort(Y.begin(), Y.end(), [&Z](const int i, const int j) { return Z[i].b > Z[j].b; });

		rdsu.init(N);
		for (int i = 0, j = 0; i < Y.size(); i++) {
			auto [t, u, w] = Z[Y[i]];
			assert(t == 2);
			for (; j < D.size() && E[D[j]].w >= w; j++) 
				rdsu.merge(E[D[j]].u, E[D[j]].v);
			int s = rdsu.rev.size();
			for (int c : J[Y[i] - ql]) 
				rdsu.merge(E[Z[c].a].u, E[Z[c].a].v);
			ans[Y[i]] = rdsu.size(u);
			rdsu.rollback(s);
		}
	}

	for (int i = 0; i < Q; i++)
		if (Z[i].t == 2)
			cout << ans[i] << '\n';
}

Compilation message (stderr)

bridges.cpp: In function 'int main()':
bridges.cpp:125:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  125 |   for (int i = 0, j = 0; i < Y.size(); i++) {
      |                          ~~^~~~~~~~~~
bridges.cpp:128:13: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  128 |    for (; j < D.size() && E[D[j]].w >= w; j++)
      |           ~~^~~~~~~~~~
In file included from /usr/include/x86_64-linux-gnu/c++/10/bits/c++allocator.h:33,
                 from /usr/include/c++/10/bits/allocator.h:46,
                 from /usr/include/c++/10/string:41,
                 from /usr/include/c++/10/bits/locale_classes.h:40,
                 from /usr/include/c++/10/bits/ios_base.h:41,
                 from /usr/include/c++/10/ios:42,
                 from /usr/include/c++/10/istream:38,
                 from /usr/include/c++/10/sstream:38,
                 from /usr/include/c++/10/complex:45,
                 from /usr/include/c++/10/ccomplex:39,
                 from /usr/include/x86_64-linux-gnu/c++/10/bits/stdc++.h:54,
                 from bridges.cpp:1:
/usr/include/c++/10/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = main()::edge; _Args = {int, int, int&}; _Tp = main()::edge]':
/usr/include/c++/10/bits/alloc_traits.h:512:17:   required from 'static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = main()::edge; _Args = {int, int, int&}; _Tp = main()::edge; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<main()::edge>]'
/usr/include/c++/10/bits/vector.tcc:115:30:   required from 'std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {int, int, int&}; _Tp = main()::edge; _Alloc = std::allocator<main()::edge>; std::vector<_Tp, _Alloc>::reference = main()::edge&]'
bridges.cpp:63:33:   required from here
/usr/include/c++/10/ext/new_allocator.h:150:4: error: new initializer expression list treated as compound expression [-fpermissive]
  150 |  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/10/ext/new_allocator.h:150:4: error: no matching function for call to 'main()::edge::edge(int&)'
bridges.cpp:58:9: note: candidate: 'main()::edge::edge()'
   58 |  struct edge { int u, v, w; };
      |         ^~~~
bridges.cpp:58:9: note:   candidate expects 0 arguments, 1 provided
bridges.cpp:58:9: note: candidate: 'constexpr main()::edge::edge(const main()::edge&)'
bridges.cpp:58:9: note:   no known conversion for argument 1 from 'int' to 'const main()::edge&'
bridges.cpp:58:9: note: candidate: 'constexpr main()::edge::edge(main()::edge&&)'
bridges.cpp:58:9: note:   no known conversion for argument 1 from 'int' to 'main()::edge&&'
In file included from /usr/include/x86_64-linux-gnu/c++/10/bits/c++allocator.h:33,
                 from /usr/include/c++/10/bits/allocator.h:46,
                 from /usr/include/c++/10/string:41,
                 from /usr/include/c++/10/bits/locale_classes.h:40,
                 from /usr/include/c++/10/bits/ios_base.h:41,
                 from /usr/include/c++/10/ios:42,
                 from /usr/include/c++/10/istream:38,
                 from /usr/include/c++/10/sstream:38,
                 from /usr/include/c++/10/complex:45,
                 from /usr/include/c++/10/ccomplex:39,
                 from /usr/include/x86_64-linux-gnu/c++/10/bits/stdc++.h:54,
                 from bridges.cpp:1:
/usr/include/c++/10/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = main()::oper; _Args = {int&, int, int&}; _Tp = main()::oper]':
/usr/include/c++/10/bits/alloc_traits.h:512:17:   required from 'static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = main()::oper; _Args = {int&, int, int&}; _Tp = main()::oper; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<main()::oper>]'
/usr/include/c++/10/bits/vector.tcc:115:30:   required from 'std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {int&, int, int&}; _Tp = main()::oper; _Alloc = std::allocator<main()::oper>; std::vector<_Tp, _Alloc>::reference = main()::oper&]'
bridges.cpp:71:29:   required from here
/usr/include/c++/10/ext/new_allocator.h:150:4: error: new initializer expression list treated as compound expression [-fpermissive]
  150 |  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/10/ext/new_allocator.h:150:4: error: no matching function for call to 'main()::oper::oper(int&)'
bridges.cpp:66:9: note: candidate: 'main()::oper::oper()'
   66 |  struct oper { int t, a, b; };
      |         ^~~~
bridges.cpp:66:9: note:   candidate expects 0 arguments, 1 provided
bridges.cpp:66:9: note: candidate: 'constexpr main()::oper::oper(const main()::oper&)'
bridges.cpp:66:9: note:   no known conversion for argument 1 from 'int' to 'const main()::oper&'
bridges.cpp:66:9: note: candidate: 'constexpr main()::oper::oper(main()::oper&&)'
bridges.cpp:66:9: note:   no known conversion for argument 1 from 'int' to 'main()::oper&&'