Submission #994548

#TimeUsernameProblemLanguageResultExecution timeMemory
994548CSQ31Keys (IOI21_keys)C++17
100 / 100
735 ms200888 KiB
#include<bits/stdc++.h> using namespace std; #define sz(a) (int)(a.size()) #define fi first #define se second typedef pair<int,int> pii; //make a graph, u->v if you start reach v starting from u //observation if u is a min scc then v must be in a min scc too! //so if we know u->v is on the graph we dont need to consider edges from u anymore const int MAXN = 3e5+5; vector<pii>adj[MAXN]; int nxt[MAXN]; int node_par[MAXN],node_sz[MAXN],tot[MAXN]; int comp_par[MAXN],comp_sz[MAXN]; set<int> keys[MAXN]; map<int,vector<int>>edges[MAXN]; queue<pii>q; vector<int>unlocked[MAXN]; int find_node(int v){ if(node_par[v] == v)return v; return node_par[v] = find_node(node_par[v]); } int find_comp(int v){ if(comp_par[v] == v)return v; return comp_par[v] = find_comp(comp_par[v]); } void merge_node(int u,int v){ u = find_node(u); v = find_node(v); if(u == v)return; if(node_sz[u] > node_sz[v])swap(u,v); for(int type:keys[u]){ keys[v].insert(type); if(edges[v].find(type) != edges[v].end()){ for(int x:edges[v][type])unlocked[v].push_back(x); edges[v].erase(type); } } for(auto z:edges[u]){ int type = z.fi; vector<int>ed = z.se; if(keys[v].find(type) != keys[v].end()){ for(int x:ed)unlocked[u].push_back(x); }else{ for(int x:ed)edges[v][type].push_back(x); } } if(sz(unlocked[u]) > sz(unlocked[v])){ for(int x:unlocked[v])unlocked[u].push_back(x); swap(unlocked[v],unlocked[u]); }else{ for(int x:unlocked[u])unlocked[v].push_back(x); } node_par[u] = v; node_sz[v] += node_sz[u]; tot[v] += tot[u]; } void merge_comp(int u,int v){ u = find_comp(u); v = find_comp(v); if(u == v)return; if(comp_sz[u] > comp_sz[v])swap(u,v); comp_par[u] = v; comp_sz[v] += comp_sz[u]; } void dfs(int u){ u = find_node(u); if(find_node(nxt[u]) != u)return; while(!unlocked[u].empty() && find_node(unlocked[u].back()) == u)unlocked[u].pop_back(); if(unlocked[u].empty())return; int v = unlocked[u].back(); v = find_node(v); //cout<<u<<" "<<v<<'\n'; unlocked[u].pop_back(); if(find_comp(u) != find_comp(v)){ nxt[u] = v; merge_comp(u,v); }else{ vector<int>path; while(v != u){ path.push_back(v); v = find_node(nxt[v]); } for(int x:path)merge_node(u,x); u = find_node(u); nxt[u] = u; } dfs(v); } vector<int> find_reachable(vector<int> r, vector<int> u, vector<int> v, vector<int> c) { int n = sz(r); vector<int>ans(n,0); for(int i=0;i<n;i++){ node_par[i] = comp_par[i] = nxt[i] = i; node_sz[i] = comp_sz[i] = 1; tot[i] = 1; //number of rooms in node keys[i].insert(r[i]); } for(int i=0;i<sz(u);i++){ if(c[i] == r[u[i]])unlocked[u[i]].push_back(v[i]); else { node_sz[u[i]]++; edges[u[i]][c[i]].push_back(v[i]); } swap(u[i],v[i]); if(c[i] == r[u[i]])unlocked[u[i]].push_back(v[i]); else { node_sz[u[i]]++; edges[u[i]][c[i]].push_back(v[i]); } } for(int i=0;i<n;i++)dfs(i); int mn = n; for(int i=0;i<n;i++){ } for(int i=0;i<n;i++){ if(i != find_node(i))continue; int j = nxt[i]; if(find_node(j) == i){ mn = min(mn,tot[i]); //cout<<tot[i]<<'\n'; } } vector<bool>good(n,0); for(int i=0;i<n;i++){ if(i != find_node(i))continue; int j = nxt[i]; if(find_node(j) == i && mn == tot[i])good[i] = 1; } for(int i=0;i<n;i++){ if(good[find_node(i)])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...