Submission #1327642

#TimeUsernameProblemLanguageResultExecution timeMemory
1327642vlomaczkKeys (IOI21_keys)C++20
0 / 100
26 ms53216 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

int M = 300'010;
vector<int> rep(M,1), sajz(M,1);
vector<set<int>> keys(M);
vector<map<int, vector<int>>> g(M);
vector<vector<int>> edges(M);

vector<int> vis(M);
int best = M;

stack<int> V;
vector<set<int>> adj(M);

int Find(int v) {
	return rep[v]==v?v:rep[v]=Find(rep[v]);
}

int Union(int a, int b) {
	// cout << a << " " << b << "\n";
	a=Find(a);
	b=Find(b);
	int res = 1;
	if(sajz[a] > sajz[b]) {
		swap(a,b);
		res = 0;
	}
	for(auto k : keys[a]) {
		if(keys[b].find(k)==keys[b].end()) {
			for(auto x : g[b][k]) edges[b].push_back(x);
		}
		keys[b].insert(k);
	}
	for(auto x : adj[a]) adj[b].insert(x);
	for(auto x : edges[a]) edges[b].push_back(x);
	rep[a] = b;
	sajz[b] += sajz[a];
	return res;
}

void dfs(int v) {
	vis[v] = 1;
	int cnt = 0;
	V.push(v);
	while(edges[v].size()) {
		auto x = Find(edges[v].back()); edges[v].pop_back();
		adj[v].insert(x);
		if(vis[x]==2) continue;
		else if(vis[x]==1) {
			while(V.size() && V.top() != x) {
				Union(V.top(), v);
				V.pop();
			}
			Union(x, v);
			vis[v] = 2;
			v = Find(v);
			V.push(v);
		} else {
			dfs(x);
		}
	}
	vis[v] = 2;
} 

vector<int> find_reachable(vector<int> R, vector<int> u, vector<int> v, vector<int> C) {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	for(int i=0; i<M; ++i) rep[i] =i;

	int n = R.size();
	int m = u.size();
	for(int i=0; i<n; ++i) {
		int x = R[i];
		keys[i].insert(x);
	}
	for(int i=0; i<m; ++i) {
		int a = u[i]; int b = v[i]; int c = C[i];
		g[a][c].push_back(b);
		g[b][c].push_back(a);
	}
	for(int i=0; i<n; ++i) {
		for(auto k : keys[i]) for(auto x : g[i][k]) edges[i].push_back(x);
	}
	for(int i=0; i<n; ++i) rep[i] = i;
	for(int i=0; i<n; ++i) {
		if(vis[i]==0) dfs(i);
	}
	for(int i=0; i<n; ++i) {
		adj[i].erase(i);
		vector<int> to_del;
		for(auto x : adj[i]) {
			if(Find(x)==i) to_del.push_back(x);
		}
		for(auto x : to_del) adj[i].erase(x);
	}
	// for(int i=0; i<n; ++i) cout << Find(i) << " "; cout << "\n";
	for(int i=0; i<n; ++i) if(adj[Find(i)].size()==0) {
		best = min(best, sajz[Find(i)]);
		// cout << Find(i) << "\n";
	}
	vector<int> ans(n);
	for(int i=0; i<n; ++i) {
		if(sajz[Find(i)]==best && adj[Find(i)].size()==0) ans[i] = 1;
	}
	return ans;
}
#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...