제출 #1261825

#제출 시각아이디문제언어결과실행 시간메모리
1261825Bui_Quoc_CuongCollapse (JOI18_collapse)C++20
컴파일 에러
0 ms0 KiB
#include <bits/stdc++.h>
// #include "collapse.h"
using namespace std;
#define FOR(i, a, b) for(int i = a; i <= (int)b; i++)
#define FORD(i, a, b) for(int i = a; i >= (int)b; i--)
#define all(a) a.begin(), a.end()
#define pb push_back
#define fi first
#define se second
const int maxN = 1e5 + 5;

int n, m, q;
array <int, 3> edges[maxN];
array <int, 2> Q[maxN];

void init() {
	cin >> n >> m >> q;
	FOR(i, 1, m) {
		cin >> edges[i][0] >> edges[i][1] >> edges[i][2];
		edges[i][1]++; edges[i][2]++;
		if (edges[i][1] > edges[i][2]) swap(edges[i][1], edges[i][2]);
	}
	FOR(i, 1, q) {
		cin >> Q[i][0] >> Q[i][1];
		Q[i][0]++; Q[i][1]++;
	}
}

namespace sub1 {
	bool checksub() {
		return max(n, q) <= 5000;
	}	

	set <int> G[5005];
	bool vis[5005];

	void dfs(int u, int p) {
		if (vis[u]) return;
		vis[u] = 1;
		for(auto v : G[u]) if (v != p && vis[v] == 0) {
			dfs(v, u);
		}
	}

	vector <int> solve() {
		vector <int> res;
		FOR(_q, 1, q) {
			FOR(i, 1, n) G[i].clear();
			int ssc = 0;

			FOR(i, 1, Q[_q][0]) {
				if (edges[i][0] == 1) {
					int u = edges[i][1], v = edges[i][2];
					if (u <= Q[_q][1] && v >= Q[_q][1] + 1) continue;
					G[u].erase(v);
					G[v].erase(u);	 
				} else {
					int u = edges[i][1], v = edges[i][2];
					if (u <= Q[_q][1] && v >= Q[_q][1] + 1) continue;
					G[u].insert(v);
					G[v].insert(u);
				}
			}

			FOR(i, 1, n) vis[i] = 0;
			FOR(i, 1, n) if (!vis[i]) {
				ssc++;
				dfs(i, i);
			}

			res.push_back(ssc);
		}
		return res;
	}	
}

struct DisjointSet{
	struct Data {
		int u, lu, v, lv, ssc;
	}; stack <Data> memo;
	int ssc, lab[maxN];

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

	bool joint(int u, int v) {
		int x = find(u), y = find(v);
		if (x == y) return false;
		if (lab[x] > lab[y]) swap(x, y);
		memo.push({x, lab[x], y, lab[y], ssc});
		lab[x]+= lab[y];
		lab[y] = x;
		ssc--;
		return true;
	}

	int get_version() {
		return (int)memo.size();
	}

	void rollback(int vers) {
		while ((int)memo.size() > vers) {
			lab[memo.top().u] = memo.top().lu;
			lab[memo.top().v] = memo.top().lv;
			ssc = memo.top().ssc;
			memo.pop();
		}
	}
} DSU;

namespace sub2 {
	bool checksub() {
		FOR(i, 1, q) if (Q[i][1] != Q[1][1]) return 0;
		return 1;
	}
	
	vector <pair <int, int>> st[4 * maxN];
	vector <int> ask[maxN];
	int ans[maxN], far_query[maxN];
	map <pair <int, int>, int> last;

	void update(int id, int l, int r, int u, int v, int id_edge) {
		if (l > v || r < u) return;
		if (l >= u && r <= v) {
			st[id].push_back(make_pair(edges[id_edge][1], edges[id_edge][2]));
			return;
		}
		int mid = (l + r) >> 1;
		update (id << 1, l, mid, u, v, id_edge);
		update (id << 1 | 1, mid + 1, r, u, v, id_edge);
	}

	void go(int id, int l, int r) {
		int vers = DSU.get_version();
		for (auto &e : st[id]) DSU.joint(e.first, e.second);
		if (l == r) {
			for (auto &id : ask[l]) {
				ans[id] = DSU.ssc;
			}
			DSU.rollback(vers);
			return;
		}
		int mid = (l + r) >> 1;
		go (id << 1, l, mid);
		go (id << 1 | 1, mid + 1, r);
		DSU.rollback(vers);
	}

	vector <int> solve() {
		int border = Q[1][1];
		FOR(i, 1, m) {
			if (edges[i][1] <= border && edges[i][2] > border) continue;
			if (edges[i][0] == 0) {
				far_query[i] = m;	
				last[make_pair(edges[i][1], edges[i][2])] = i;	
			} else {
				far_query[last[make_pair(edges[i][1], edges[i][2])]] = i - 1;
			}
		}
		FOR(i, 1, m) if (edges[i][0] == 0) {
			update(1, 1, m, i, far_query[i], i);
		}
		FOR(i, 1, q) ask[Q[i][0]].push_back(i);
		FOR(i, 1, n) DSU.lab[i] = - 1;
		DSU.ssc = n;
		go(1, 1, m);
		vector <int> res;
		FOR(i, 1, q) res.push_back(ans[i]);
		// FOR(i, 1, q) cout << ans[i] << " ";
		return res;
	}
}

namespace sub3 {
	int ans[maxN];
	set <pair <int, int>> out_block, in_block;
	vector <pair <int, int>> eblock[maxN];
	vector <int> ask[maxN], askp[maxN];
	vector <int> g[maxN];

	void solve() {
		FOR(i, 1, q) ask[Q[i][0]].push_back(i);
		for (int i = 1; i <= m; i+= 320) {
			int L = i, R = min(m, i + 320 - 1) - 1;
			in_block.clear();
			FOR(j, 1, n) askp[j].clear();

			FOR(j, L, R) {
				int u = edges[j][1], v = edges[j][2];
				if (out_block.find(make_pair(u, v)) != out_block.end()) {
					out_block.erase(make_pair(u, v));
					in_block.insert(make_pair(u, v));
				}
				for (auto id : ask[j]) askp[Q[id][1]].push_back(id);
			}

			FOR(j, L, R) {
				int u = edges[j][1], v = edges[j][2];
				if (edges[j][0] == 0) {
					in_block.insert(make_pair(u, v));
				} else in_block.erase(make_pair(u, v));
				for (auto it : in_block) eblock[j].push_back(it);
			}

			FOR(j, 1, n) {
				DSU.lab[j] = - 1;
				g[j].clear();
				DSU.ssc = n;
			}
			while (!DSU.memo.empty()) DSU.memo.pop();
			for (auto x : out_block) g[x.se].push_back(x.fi);

			FOR(j, 1, n) {
				for (auto x : g[j]) DSU.joint(x, j);
				int vers = DSU.get_version();
				for (auto id : askp[j]) {
					for (auto x : eblock[Q[id][0]]) {
						if (max(x.first, x.second) <= j) DSU.joint(x.first, x.second);
					}
					ans[id]+= DSU.ssc;
					DSU.rollback(vers);
				}
			}

			FOR(j, 1, n) {
				DSU.lab[j] = - 1;
				g[j].clear();
				DSU.ssc = n;
			}
			while (!DSU.memo.empty()) DSU.memo.pop();
			for (auto x : out_block) g[x.fi].push_back(x.se);

			FORD(j, n, 1) {
				int vers = DSU.get_version();
				for (auto id : askp[j]) {
					for (auto x : eblock[Q[id][0]]) {
						if (min(x.first, x.second) > j) DSU.joint(x.first, x.second);
					}
					ans[id]+= DSU.ssc;
					DSU.rollback(vers);
				}
				for (auto x : g[j]) DSU.joint(x, j);
			}

			for (auto x : in_block) out_block.insert(x);
		}	

		FOR(i, 1, q) cout << ans[i] - n << " ";
	}
}

vector <int> simulateCollapse(int N, vector<int> T, vector<int> X, vector<int> Y, vector<int> W, vector<int> P) {
	n = N;
	m = X.size();
	q = W.size();
	FOR(i, 0, m - 1) {
		edges[i + 1][0] = T[i];
		edges[i + 1][1] = X[i] + 1;
		edges[i + 1][2] = Y[i] + 1;
		if (edges[i + 1][1] > edges[i + 1][2]) swap(edges[i + 1][1], edges[i + 1][2]);
	}
	for (int i = 0; i < q; i++) {
		Q[i + 1][0] = W[i] + 1;
		Q[i + 1][1] = P[i] + 1;
	}	
	vector <int> res;
	if (sub1::checksub()) res = sub1::solve();
	else if (sub2::checksub()) res = sub2::solve(); 
	else res = sub3::solve();
	return res;
}

void process() {
	vector <int> res;
	// if (sub1::checksub()) res = sub1::solve();
	// for (int &val : res) cout << val << " ";
	// cout << "\n";
	// if (sub2::checksub()) res = sub2::solve();	
	// for (int &val : res) cout << val << " ";
	// cout << "\n";
	sub3::solve();
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    #define ko "kieuoanh"
    if (fopen(ko".inp", "r")) { 
        freopen(ko".inp", "r", stdin); 
        freopen(ko".out", "w", stdout);
    }
    init();
    process();
    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

collapse.cpp: In function 'std::vector<int> simulateCollapse(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
collapse.cpp:270:32: error: no match for 'operator=' (operand types are 'std::vector<int>' and 'void')
  270 |         else res = sub3::solve();
      |                                ^
In file included from /usr/include/c++/11/vector:72,
                 from /usr/include/c++/11/functional:62,
                 from /usr/include/c++/11/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/11/algorithm:74,
                 from /usr/include/x86_64-linux-gnu/c++/11/bits/stdc++.h:65,
                 from collapse.cpp:1:
/usr/include/c++/11/bits/vector.tcc:198:5: note: candidate: 'std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = int; _Alloc = std::allocator<int>]'
  198 |     vector<_Tp, _Alloc>::
      |     ^~~~~~~~~~~~~~~~~~~
/usr/include/c++/11/bits/vector.tcc:199:42: note:   no known conversion for argument 1 from 'void' to 'const std::vector<int>&'
  199 |     operator=(const vector<_Tp, _Alloc>& __x)
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
In file included from /usr/include/c++/11/vector:67,
                 from /usr/include/c++/11/functional:62,
                 from /usr/include/c++/11/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/11/algorithm:74,
                 from /usr/include/x86_64-linux-gnu/c++/11/bits/stdc++.h:65,
                 from collapse.cpp:1:
/usr/include/c++/11/bits/stl_vector.h:709:7: note: candidate: 'std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(std::vector<_Tp, _Alloc>&&) [with _Tp = int; _Alloc = std::allocator<int>]'
  709 |       operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
      |       ^~~~~~~~
/usr/include/c++/11/bits/stl_vector.h:709:26: note:   no known conversion for argument 1 from 'void' to 'std::vector<int>&&'
  709 |       operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
      |                 ~~~~~~~~~^~~
/usr/include/c++/11/bits/stl_vector.h:730:7: note: candidate: 'std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(std::initializer_list<_Tp>) [with _Tp = int; _Alloc = std::allocator<int>]'
  730 |       operator=(initializer_list<value_type> __l)
      |       ^~~~~~~~
/usr/include/c++/11/bits/stl_vector.h:730:46: note:   no known conversion for argument 1 from 'void' to 'std::initializer_list<int>'
  730 |       operator=(initializer_list<value_type> __l)
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
collapse.cpp: In function 'int main()':
collapse.cpp:290:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  290 |         freopen(ko".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
collapse.cpp:291:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  291 |         freopen(ko".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~