#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define ull unsigned long long
#define ff first
#define ss second
#define pii pair<int,int>
#define pll pair<long long, long long>
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define siz(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace __gnu_pbds;
using namespace std;
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());}
//ll los(ll a, ll b) {return a + (mt() % (b-a+1));}
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
const ll MOD = 1e9+7;
//comp
set<pii> not_use_edges[300'001];
vi use_edges[300'001];
set<int> keys[300'001];
int siz_[300'001];
int comp_nr[300'001];
int last_iter[300'001];
vi comp_list[300'001];
int R[300'001];
int cur_iter = 1;
void onion(int a, int b)
{
a = comp_nr[a];
b = comp_nr[b];
if(a == b) return;
if(siz_[a] > siz_[b]) swap(a,b);
siz_[b] += siz_[a];
forall(it,comp_list[a])
{
comp_list[b].pb(it);
comp_nr[it] = b;
}
forall(it,use_edges[a])
{
use_edges[b].pb(it);
}
forall(it,not_use_edges[a])
{
if(keys[b].find(it.ff) != keys[b].end())
{
use_edges[b].pb(it.ss);
}
else
{
not_use_edges[b].insert(it);
}
}
forall(it,keys[a])
{
auto f = not_use_edges[b].lower_bound({it,-1});
while(f != not_use_edges[b].end() && (*f).ff == it)
{
use_edges[b].pb((*f).ss);
not_use_edges[b].erase(f);
f = not_use_edges[b].lower_bound({it,-1});
}
keys[b].insert(it);
}
}
vi find_reachable(vi r, vi u, vi v, vi c)
{
int n = siz(r);
int m = siz(u);
rep(i,n)
{
R[i] = r[i];
keys[i].insert(r[i]);
siz_[i] = 1;
comp_nr[i] = i;
comp_list[i].pb(i);
}
rep(i,m)
{
if(keys[u[i]].find(c[i]) == keys[u[i]].end())
{
not_use_edges[u[i]].insert({c[i],v[i]});
}
else
{
use_edges[u[i]].pb(v[i]);
}
if(keys[v[i]].find(c[i]) == keys[v[i]].end())
{
not_use_edges[v[i]].insert({c[i],u[i]});
}
else
{
use_edges[v[i]].pb(u[i]);
}
}
pair<int,vi> ans = {1e9,{}};
rep(i,n)
{
cur_iter++;
if(last_iter[comp_nr[i]] != 0) continue;
int cur_comp = comp_nr[i];
vi comps = {};
while(true)
{
last_iter[cur_comp] = cur_iter;
if(siz(use_edges[cur_comp]) == 0)
{
if(siz_[cur_comp] < ans.ff)
{
ans.ff = siz_[cur_comp];
ans.ss = comp_list[cur_comp];
}
else if(siz_[cur_comp] == ans.ff)
{
forall(it,comp_list[cur_comp])
{
ans.ss.pb(it);
}
}
break;
}
int nxt = use_edges[cur_comp].back();
use_edges[cur_comp].pop_back();
nxt = comp_nr[nxt];
if(cur_comp == nxt) continue;
if(last_iter[nxt] == 0)
{
comps.pb(cur_comp);
cur_comp = nxt;
continue;
}
if(last_iter[nxt] == cur_iter)
{
while(true)
{
onion(cur_comp,comps.back());
if(comps.back() == nxt)
{
comps.pop_back();
break;
}
comps.pop_back();
}
cur_comp = comp_nr[cur_comp];
last_iter[cur_comp] = cur_iter;
comps.pb(cur_comp);
}
else break;
}
}
vector<int> ans_(n,0);
forall(it,ans.ss) ans_[it] = 1;
return ans_;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |