結果
| 問題 |
No.2290 UnUnion Find
|
| コンテスト | |
| ユーザー |
Gandalfr
|
| 提出日時 | 2023-09-30 01:31:48 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 413 ms / 2,000 ms |
| コード長 | 3,992 bytes |
| コンパイル時間 | 2,022 ms |
| コンパイル使用メモリ | 207,212 KB |
| 最終ジャッジ日時 | 2025-02-17 03:44:57 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 46 |
ソースコード
#line 1 "playspace/main.cpp"
#include <bits/stdc++.h>
#line 3 "library/gandalfr/data_structure/union_find.hpp"
#line 6 "library/gandalfr/data_structure/union_find.hpp"
class union_find {
private:
int N;
mutable std::vector<int> par;
std::vector<int> nxt;
int group_num; // 集合の数
public:
union_find() : N(0), group_num(0) {}
union_find(int n) : N(n), par(n, -1), nxt(n), group_num(n) {
std::iota(nxt.begin(), nxt.end(), 0);
}
/**
* @brief 頂点を n 個に増やす
* @attention 小さくはできない
*/
void expand(int n) {
if (n <= N)
return;
par.resize(n, -1);
nxt.resize(n);
for (int i = N; i < n; ++i)
nxt[i] = i;
group_num += n - N;
N = n;
}
int leader(int x) const {
return (par[x] < 0 ? x : par[x] = leader(par[x]));
}
bool same(int x, int y) const { return leader(x) == leader(y); }
bool merge(int x, int y) {
if ((x = leader(x)) == (y = leader(y)))
return false;
if (-par[x] > -par[y])
std::swap(x, y);
par[x] += par[y];
par[y] = x;
std::swap(nxt[x], nxt[y]);
group_num--;
return true;
}
/**
* @brief x の属するグループのサイズを返す
*/
int size(int x) const { return -par[leader(x)]; }
/**
* @brief すべてのノードの数
*/
int size() const { return N; }
std::vector<int> group_containing_node(int x) const {
std::vector<int> ret{x};
for (int cu = nxt[x]; cu != ret[0]; cu = nxt[cu])
ret.push_back(cu);
return ret;
}
int count_groups() const { return group_num; }
std::vector<std::vector<int>> all_groups() const {
std::vector<std::vector<int>> result;
result.reserve(group_num);
std::vector<bool> used(N, false);
for (int i = 0; i < N; ++i) {
if (!used[i]) {
result.emplace_back(group_containing_node(i));
for (int x : result.back()) {
used[x] = true;
}
}
}
return result;
}
};
#line 3 "playspace/main.cpp"
using namespace std;
using ll = long long;
const int INF = 1001001001;
const ll INFLL = 1001001001001001001;
const ll MOD = 1000000007;
const ll _MOD = 998244353;
#define rep(i, j, n) for(ll i = (ll)(j); i < (ll)(n); i++)
#define rrep(i, j, n) for(ll i = (ll)(n-1); i >= (ll)(j); i--)
#define all(a) (a).begin(),(a).end()
#define debug(a) std::cerr << #a << ": " << a << std::endl
#define LF cout << endl
#ifdef ENABLE_MULTI_FOR
#define mrep(it, mr) for(multi_iter it(mr); !it.fin(); ++it)
#endif
template<typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
template<typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }
void Yes(bool ok){ std::cout << (ok ? "Yes" : "No") << std::endl; }
int main(void){
int N, Q;
cin >> N >> Q;
union_find G(N);
set<int> st;
rep(i,0,N) {st.insert(i);}
rep(i,0,Q) {
int q;
cin >> q;
if (q == 1) {
int u, v;
cin >> u >> v;
u--, v--;
if (G.same(u, v)) {
continue;
}
u = G.leader(u);
v = G.leader(v);
if (G.size(u) > G.size(v)) {
swap(u, v);
}
G.merge(u, v);
st.erase(v);
} else {
int x;
cin >> x;
x--;
x = G.leader(x);
if (st.size() == 1) {
cout << -1 << endl;
} else {
auto it = st.begin();
if (*it != x) {
cout << *it + 1 << endl;
} else {
cout << *++it + 1 << endl;
}
}
}
}
}
Gandalfr