이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#ifdef NYAOWO
#include "grader.cpp"
#endif
#include <bits/stdc++.h>
#define For(i, a, b) for(int i = a; i <= b; i++)
#define Forr(i, a, b) for(int i = a; i >= b; i--)
#define F first
#define S second
#define sz(x) ((int)x.size())
#define all(x) x.begin(), x.end()
#define eb emplace_back
// #define int LL
using namespace std;
using i32 = int32_t;
using LL = long long;
using pii = pair<int, int>;
const int MAXN = 300'000;
const int MAXK = 30; // max types of keys
const int MAXND = MAXN * MAXK;
struct DSU {
int p[MAXN + 10];
void init() {
memset(p, -1, sizeof(p));
}
int find(int n) {
if(p[n] < 0) return n;
return p[n] = find(p[n]);
}
void uni(int a, int b) {
a = find(a); b = find(b);
if(a != b) p[b] = a;
}
} dsu[MAXK + 10];
struct SCC {
vector<int> adj[MAXND + 10];
vector<int> rev[MAXND + 10];
int vis[MAXND + 10];
vector<int> stk;
vector<int> scc[MAXND + 10];
bool broken[MAXND + 10];
int rk2id(int r, int k) {
return r * MAXK + k;
}
pii id2rk(int id) {
return pii(id / MAXK, id % MAXK);
}
void link(int r1, int k1, int r2, int k2) {
int x = rk2id(r1, k1);
int y = rk2id(r2, k2);
adj[x].eb(y);
rev[y].eb(x);
}
void bilink(int r1, int k1, int r2, int k2) {
link(r1, k1, r2, k2);
link(r2, k2, r1, k1);
}
void dfs1(int n) {
if(vis[n] < 0) return;
vis[n] = -1;
for(auto &i:rev[n]) dfs1(i);
stk.eb(n);
}
void dfs2(int n, int tag) {
if(vis[n] != -1 && vis[n] != tag) broken[tag] = 1;
if(vis[n] != -1) return;
vis[n] = tag;
for(auto &i:adj[n]) dfs2(i, tag);
}
int build_scc(int n) {
memset(vis, 0, sizeof(vis));
For(i, 0, n * MAXK - 1) dfs1(i);
int cur_scc = 0;
while(sz(stk)) {
dfs2(stk.back(), cur_scc);
while(sz(stk) && vis[stk.back()] != -1) stk.pop_back();
cur_scc++;
}
For(i, 0, n * MAXK - 1) {
scc[vis[i]].eb(i);
}
return cur_scc;
}
} ayaya;
int in_use[MAXN + 10];
vector<i32> find_reachable(vector<i32> R, vector<i32> U, vector<i32> V, vector<i32> C) {
int n = sz(R);
int m = sz(C);
For(i, 0, MAXK - 1) dsu[i].init();
For(i, 0, m - 1) dsu[C[i]].uni(U[i], V[i]);
For(k, 0, 29) For(r, 0, n - 1) {
ayaya.bilink(r, k, dsu[k].find(r), k);
ayaya.link(r, k, r, R[r]);
}
int nscc = ayaya.build_scc(n);
vector<int> reach(n, -1);
int mn = n + 48763;
For(sccid, 0, nscc - 1) if(!ayaya.broken[sccid]) {
int cnt = 0;
vector<int> start;
for(auto &id:ayaya.scc[sccid]) {
int r, k;
tie(r, k) = ayaya.id2rk(id);
if(k == R[r]) start.eb(r);
cnt += (in_use[r] == 0);
in_use[r] = 1;
}
for(auto &i:start) {
reach[i] = cnt;
mn = min(mn, cnt);
}
for(auto &id:ayaya.scc[sccid]) {
in_use[ayaya.id2rk(id).F] = 0;
}
}
vector<i32> ans(n);
For(i, 0, n - 1) {
ans[i] = (reach[i] == mn);
}
return ans;
}
/*
4 5
0 1 1 2
0 1 0
0 2 0
1 2 1
1 3 0
3 1 2
0 1 1 0
7 10
0 1 1 2 2 1 2
0 1 0
0 2 0
1 2 1
1 3 0
2 3 0
3 4 1
3 5 2
4 5 0
4 6 2
5 6 1
0 1 1 0 1 0 1
3 1
0 0 0
0 1 0
0 0 1
*/
# | 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... |