Submission #1059722

#TimeUsernameProblemLanguageResultExecution timeMemory
1059722pccKeys (IOI21_keys)C++17
100 / 100
591 ms126040 KiB
#include <vector> #include <bits/stdc++.h> using namespace std; #pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2,popcnt,sse4") #define pii pair<int,int> #define fs first #define sc second const int mxn = 3e5+10; set<int> heads; struct DSU{ set<int> keys[mxn]; vector<pii> edges[mxn]; int dsu[mxn],sz[mxn]; DSU(){ iota(dsu,dsu+mxn,0); fill(sz,sz+mxn,1); } int root(int k){ return k == dsu[k]?k:dsu[k] = root(dsu[k]); } void onion(int a,int b){ a = root(a),b = root(b); if(a == b)return; if(heads.find(b) != heads.end())heads.erase(b); if(sz[a]<sz[b])swap(a,b); dsu[b] = a; sz[a] += sz[b]; if(edges[a].size()<edges[b].size())edges[a].swap(edges[b]); if(keys[a].size()<keys[b].size())keys[a].swap(keys[b]); for(auto &i:keys[b])keys[a].insert(i); while(!edges[b].empty()){ auto now = edges[b].back();edges[b].pop_back(); if(root(now.fs) == a)continue; edges[a].push_back(now); } return; } }; DSU dsu; int N; namespace SHRINK{ vector<int> paths[mxn]; bitset<mxn> done; int idx[mxn],low[mxn]; vector<int> st; int cnt = 0; bool flag = false; void dfs(int now){ idx[now] = low[now] = ++cnt; st.push_back(now); for(auto nxt:paths[now]){ if(done[nxt])continue; if(!idx[nxt]){ dfs(nxt); low[now] = min(low[now],low[nxt]); } else low[now] = min(low[now],idx[nxt]); } if(low[now] == idx[now]){ if(st.back() != now)flag = true; while(st.back() != now){ dsu.onion(now,st.back()); done[st.back()] = true; st.pop_back(); } done[st.back()] = true; st.pop_back(); } return; } bool GO(){ cnt = 0; flag = false; for(auto &now:heads){ for(auto &[nxt,w]:dsu.edges[now]){ nxt = dsu.root(nxt); if(nxt != now&&dsu.keys[now].find(w) != dsu.keys[now].end()){ paths[now].push_back(nxt); } } } for(auto &i:heads){ if(!done[i])dfs(i); } for(auto &i:heads){ done[i] = false; idx[i] = low[i] = 0; } return flag; } } namespace ANSWER{ bitset<mxn> leaf; vector<int> GO(){ leaf.set(); int mn = 1e9; for(auto &now:heads){ for(auto &[nxt,w]:dsu.edges[now]){ nxt = dsu.root(nxt); if(nxt == now)continue; if(dsu.keys[now].find(w) != dsu.keys[now].end())leaf[now] = false; } if(leaf[now])mn = min(mn,dsu.sz[now]); } vector<int> ans(N,0); for(int i = 0;i<N;i++){ int now = dsu.root(i); if(!leaf[now]||dsu.sz[now] != mn)ans[i] = false; else ans[i] = true; } return ans; } } std::vector<int> find_reachable(std::vector<int> r, std::vector<int> u, std::vector<int> v, std::vector<int> c) { N = r.size(); for(int i = 0;i<N;i++)heads.insert(i); for(int i = 0;i<N;i++){ dsu.keys[i].insert(r[i]); } for(int i = 0;i<u.size();i++){ int a = u[i],b = v[i],tp = c[i]; dsu.edges[a].push_back(pii(b,tp)); dsu.edges[b].push_back(pii(a,tp)); } int cnt = 0; while(SHRINK::GO()){ cnt++; } assert(cnt<=30); cerr<<cnt<<" epoches"<<endl; return ANSWER::GO(); }

Compilation message (stderr)

keys.cpp: In function 'std::vector<int> find_reachable(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
keys.cpp:129:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  129 |  for(int i = 0;i<u.size();i++){
      |                ~^~~~~~~~~
#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...