제출 #872885

#제출 시각아이디문제언어결과실행 시간메모리
872885lighton열쇠 (IOI21_keys)C++17
100 / 100
949 ms259760 KiB
#include<bits/stdc++.h> #pragma GCC optimize("O3") #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #define all(v) (v).begin(), (v).end() using namespace std; using pi = pair<int,int>; struct CC{ int grp[300001]; int fi(int x){ if(grp[x] == x) return x; else return grp[x] = fi(grp[x]); } void un(int x, int y){ x = fi(x); y = fi(y); assert(x!=y); grp[x] = y; } } cc; vector<int> R,U,V,C; struct CYCLES{ int grp[300001]; int siz[300001]; set<int> components[300001]; set<int> colors[300001]; set<pi> edges[300001]; vector<int> reach[300001]; int fi(int x){ if(grp[x] == x) return x; else return grp[x] = fi(grp[x]); } void un(int x, int y){ x = fi(x); y = fi(y); assert(x!=y); if(siz[x] > siz[y]) swap(x,y); siz[y] += siz[x]; for(auto &i :components[x]){ components[y].insert(i); } for(auto &i :colors[x]){ if(colors[y].find(i) == colors[y].end()) { colors[y].insert(i); auto it = edges[y].lower_bound({i,-1}); while(it != edges[y].end() && it->first == i){ reach[y].push_back(it->second); it = edges[y].erase(it); } } } for(auto &[i,j] : edges[x]){ if(colors[y].find(i) != colors[y].end()){ reach[y].push_back(j); } else edges[y].insert({i,j}); } for(auto &i : reach[x]) reach[y].push_back(i); while(reach[y].size() && components[y].find(reach[y].back()) != components[y].end()){ reach[y].pop_back(); } grp[x] = y; } } cycles; int N,M; vector<pi> adj[300001]; int chk[300001]; vector<pi> candidate; int ans = 1e9; std::vector<int> find_reachable(std::vector<int> r, std::vector<int> u, std::vector<int> v, std::vector<int> c) { N = r.size(); M = u.size(); R=r;U=u;V=v;C=c; for(int i = 0; i<M; i++){ adj[U[i]].push_back({V[i],C[i]}); adj[V[i]].push_back({U[i],C[i]}); } //init for(int i = 0; i<N; i++){ cc.grp[i] = i; cycles.grp[i] = i; } for(int i = 0; i<N; i++){ cycles.components[i].insert(i); cycles.colors[i].insert(R[i]); for(auto &j : adj[i]){ if(j.second == R[i]) cycles.reach[i].push_back(j.first); else cycles.edges[i].insert({j.second,j.first}); cycles.siz[i]++; } while(cycles.reach[cycles.fi(i)].size() && cc.fi(cycles.reach[cycles.fi(i)].back()) == cc.fi(i)){ cycles.un(i,cycles.reach[cycles.fi(i)].back()); } if(cycles.reach[cycles.fi(i)].empty()){ int tmp = cycles.components[cycles.fi(i)].size(); for(int j : cycles.components[cycles.fi(i)]) candidate.push_back({j,tmp}); ans = min(ans,tmp); } else{ cc.un(cycles.reach[cycles.fi(i)].back(),i); } } std::vector<int> ret(N, 0); for(auto &[i,j] : candidate){ if(j==ans) ret[i] = 1; } return ret; }
#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...