Submission #596769

#TimeUsernameProblemLanguageResultExecution timeMemory
596769balbitKeys (IOI21_keys)C++17
100 / 100
1399 ms247528 KiB
#include <vector> #include <bits/stdc++.h> #ifndef BALBIT #include "keys.h" #endif using namespace std; #define ll long long #define pii pair<int, int> #define f first #define s second #define REP(i,n) for (int i = 0; i<n; ++i) #define REP1(i,n) for (int i = 1; i<=n; ++i) #define MX(a,b) a = max(a,b) #define MN(a,b) a = min(a,b) #define pb push_back #define SZ(x) (int)(x).size() #define ALL(x) (x).begin(), (x).end() #ifdef BALBIT #define bug(...) cerr<<"#"<<__LINE__<<": "<<#__VA_ARGS__<<"- ", _do(__VA_ARGS__) template<typename T> void _do(T && x) {cerr<<x<<endl;} template<typename T, typename ...S> void _do(T && x, S && ...y) {cerr<<x<<", "; _do(y...);} #else #define bug(...) #endif // BALBIT const int maxn = 3e5+5; int /*head[maxn], */par[maxn]; // int szedges[maxn]; // size of number of edges left unordered_map<int, vector<int> > E[maxn]; // edges not done being worked unordered_set<int> todo[maxn]; unordered_set<int> owned[maxn]; // todo is a subset of owned vector<int> nhere[maxn]; // nodes in this unordered_set int find(int x){return x == par[x]? x : par[x] = find(par[x]);} inline int WHO(int x){return find(x);} int dead[maxn]; // 1: this head is dead, 2: this head touches a dead, so it's super dead int getone(int v) { while (!todo[v].empty()) { int c = *todo[v].begin(); if (!E[v].count(c)) { todo[v].erase(c); continue; } // bug(v,c,SZ(E[v][c])); while (SZ(E[v][c])) { int go = WHO(E[v][c].back()); E[v][c].pop_back(); if (dead[go]) { bug(v, go, "dead!"); return -2; } if (go != v) bug(v,go); if (go!=v) return go; } E[v].erase(c); todo[v].erase(c); } return -1; } void mrg(int a, int b, int newhead) { if (SZ(nhere[a]) < SZ(nhere[b])) swap(a,b); // a is the greater one for (int x : owned[b]) { if (owned[a].insert(x).s) { if (E[a].count(x)) { todo[a].insert(x); } } } for (auto &p : E[b]) { if (owned[a].count(p.f)) todo[a].insert(p.f); // consider merging todo later (?) E[a][p.f].insert(E[a][p.f].end(), ALL(p.s)); } nhere[a].insert(nhere[a].end(), ALL(nhere[b])); unordered_map<int, vector<int> >().swap(E[b]); unordered_set<int>().swap(owned[b]); unordered_set<int>().swap(todo[b]); vector<int>().swap(nhere[b]); if (newhead != a) { assert(newhead == b); E[a].swap(E[b]); owned[a].swap(owned[b]); todo[a].swap(todo[b]); nhere[a].swap(nhere[b]); par[a] = b; }else{ par[b] = a; } } vector<int> stk; bool instk[maxn]; void runstack(){ while (!stk.empty()) { int v = stk.back(); int to = getone(v); assert(to != v); if (to == -1) { dead[v] = 1; instk[v] = 0; stk.pop_back(); to = -2; } if (to == -2) { for (int e : stk) { dead[e] = 2; instk[e] = 0; } stk.clear(); return; } if (!instk[to]) { instk[to] = 1; stk.pb(to); continue; }else{ while (stk.back() != to) { int last = stk.back(); instk[last] = 0; stk.pop_back(); int pl = stk.back(); mrg(last, pl, pl); } } } } std::vector<int> find_reachable(std::vector<int> r, std::vector<int> u, std::vector<int> v, std::vector<int> c) { std::vector<int> ans(r.size(), 1); int n = SZ(r); int m = SZ(u); REP(i,m) { int U = u[i], V = v[i], C = c[i]; REP(barbar, 2) { E[U][C].pb(V); swap(U,V); } } REP(i,n) { par[i] = i; nhere[i].pb(i); owned[i].insert(r[i]); if (E[i].count(r[i])) { todo[i].insert(r[i]); bug(i, "todo", r[i]); } } REP(i,n) { if (!dead[i]) { instk[i] = 1; stk.pb(i); runstack(); } } vector<int> raw(n, n+1); REP(i,n) { int FI = find(i); bug(i, dead[i], FI); if (FI == i && dead[i] != 2) { for (int e : nhere[i]) { raw[e] = SZ(nhere[i]); } } } REP(i,n) { bug(i, raw[i]); } int mne = *min_element(ALL(raw)); for (int &e : raw) { e = (e==mne?1:0); } return raw; } #ifdef BALBIT signed main(){ // vector<int> yay = find_reachable({0, 1, 1, 2, 2, 1, 2}, // {0, 0, 1, 1, 2, 3, 3, 4, 4, 5}, // {1, 2, 2, 3, 3, 4, 5, 5, 6, 6}, // {0, 0, 1, 0, 0, 1, 2, 0, 2, 1}); vector<int> yay = find_reachable({0, 0, 0}, {0}, {1}, {0}); for (int t : yay) bug(t); } #endif
#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...