This documentation is automatically generated by competitive-verifier/competitive-verifier
#define PROBLEM "https://judge.yosupo.jp/problem/incremental_minimum_spanning_forest"
#include <bits/stdc++.h>
using namespace std;
#include "tree/link_cut.hpp"
struct node : lct_node<node> {
using lct_node<node>::lct_node;
pair<int, int> val{0, -1}, path{0, -1};
void pull() { path = max({$(l)->path, val, $(r)->path}); }
void set(pair<int, int> a) { val = a; }
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n, m;
cin >> n >> m;
LCT<node> tr(n + m);
vector<int> v(m), u(m);
for (int i = 0, w; i < m; i++) {
cin >> u[i] >> v[i] >> w;
tr.set(i + n, pair{w, i});
int ans = -1;
if (u[i] == v[i]) {
cout << i << "\n";
continue;
}
if (tr.lca(u[i], v[i]) == -1) {
cout << -1 << " \n"[i == m - 1];
tr.link(u[i], i + n);
tr.link(v[i], i + n);
continue;
}
tr.expose_path(u[i], v[i]);
auto [mx, id] = tr[v[i]]->path;
if (w > mx) {
ans = i;
} else {
ans = id;
tr.cut(u[id], id + n), tr.cut(v[id], id + n);
}
cout << ans << " \n"[i == m - 1];
if (ans != i) {
tr.link(u[i], i + n);
tr.link(v[i], i + n);
}
}
}
#line 1 "test/yosupo/graph/incremental_minimum_spanning_forest.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/incremental_minimum_spanning_forest"
#include <bits/stdc++.h>
using namespace std;
#line 2 "tree/link_cut.hpp"
template<class node> struct LCT {
using ptr = node *;
vector<node> nodes;
LCT(int n = 0) : nodes(n) {}
auto operator[](int i) { return &nodes[i]; }
int id(ptr t) { return int(t - &nodes[0]); }
void splay(int v) { splay(&nodes[v]); }
void expose(int v) { expose(&nodes[v]); }
void expose_path(int u, int v) { evert(u), expose(v); }
void evert(int v) { evert(&nodes[v]); }
void link(int v, int p) { link(&nodes[v], &nodes[p]); }
void cut(int v, int p) { cut(&nodes[v], &nodes[p]); }
int lca(int u, int v) {
ptr l = lca(&nodes[u], &nodes[v]);
return l ? id(l) : -1;
}
template<class... T> void set(int v, T &&...x) {
expose(v), nodes[v].set(x...);
}
template<class... T> void add(int v, T &&...x) {
expose(v), nodes[v].add(x...);
}
static void splay(ptr t) {
for (t->_push(); state(t); rot(t)) {
ptr p = t->p, g = p->p;
if (g) g->_push();
p->_push(), t->_push();
if (state(p)) rot(state(t) == state(p) ? p : t);
}
}
static ptr expose(ptr t) {
ptr prv = 0;
for (ptr cur = t; cur; cur = cur->p) {
splay(cur);
if (cur->r) cur->_add_light(cur->r);
if (prv) cur->_sub_light(prv);
attach(cur, 1, exchange(prv, cur));
}
splay(t);
return prv;
}
static void evert(ptr t) { expose(t), t->_flip(); }
static void link(ptr v, ptr p) {
evert(v), expose(p);
assert(!v->p && !p->r);
attach(p, 1, v);
}
static void cut(ptr v, ptr p) {
evert(p), expose(v);
assert(!v->p && v->l == p);
attach(v, 0, p->p = 0);
}
static ptr lca(ptr u, ptr v) {
if (u == v) return u;
expose(u);
ptr l = expose(v);
return u->p ? l : 0;
}
static ptr &ch(ptr t, bool d) { return d ? t->r : t->l; }
static void attach(ptr p, int d, ptr c) {
if (c) c->p = p;
ch(p, d) = c, p->pull();
}
static int state(ptr t) {
if (!t->p) return 0;
return t == t->p->l ? -1 : t == t->p->r ? 1 : 0;
}
static void rot(ptr t) {
ptr p = t->p, g = p->p;
int d = state(t) == 1, dp = state(p);
t->p = p->p;
if (g) dp ? attach(g, dp == 1, t) : g->_change_light(p, t);
attach(p, d, ch(t, !d));
attach(t, !d, p);
}
};
template<class node> struct lct_node {
using ptr = node *;
static ptr $(ptr t) {
static node nil;
return t ?: &nil;
}
ptr p = 0, l = 0, r = 0;
bool rev = 0;
node *as_derived() { return (node *)this; };
void _push() {
if (exchange(rev, 0)) $(l)->_flip(), $(r)->_flip();
if constexpr (has_push<node>) as_derived()->push();
}
void _flip() {
swap(l, r), rev ^= 1;
if constexpr (has_flip<node>) as_derived()->flip();
}
void _add_light(ptr c) {
if constexpr (has_add_light<node>) as_derived()->add_light(c);
}
void _sub_light(ptr c) {
if constexpr (has_sub_light<node>) as_derived()->sub_light(c);
}
void _change_light(ptr prv, ptr cur) {
if constexpr (has_change_light<node>)
as_derived()->change_light(prv, cur);
}
// rip compile time
#define CHECK(a) \
template<class T, class = void> struct has_##a##_t : false_type {}; \
template<class T> struct has_##a##_t<T, void_t<decltype(&T::a)>> : true_type {}; \
template<class T> static constexpr bool has_##a = has_##a##_t<T>::value;
CHECK(push) CHECK(flip)
CHECK(add_light) CHECK(sub_light) CHECK(change_light)
#undef CHECK
};
#line 7 "test/yosupo/graph/incremental_minimum_spanning_forest.test.cpp"
struct node : lct_node<node> {
using lct_node<node>::lct_node;
pair<int, int> val{0, -1}, path{0, -1};
void pull() { path = max({$(l)->path, val, $(r)->path}); }
void set(pair<int, int> a) { val = a; }
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n, m;
cin >> n >> m;
LCT<node> tr(n + m);
vector<int> v(m), u(m);
for (int i = 0, w; i < m; i++) {
cin >> u[i] >> v[i] >> w;
tr.set(i + n, pair{w, i});
int ans = -1;
if (u[i] == v[i]) {
cout << i << "\n";
continue;
}
if (tr.lca(u[i], v[i]) == -1) {
cout << -1 << " \n"[i == m - 1];
tr.link(u[i], i + n);
tr.link(v[i], i + n);
continue;
}
tr.expose_path(u[i], v[i]);
auto [mx, id] = tr[v[i]]->path;
if (w > mx) {
ans = i;
} else {
ans = id;
tr.cut(u[id], id + n), tr.cut(v[id], id + n);
}
cout << ans << " \n"[i == m - 1];
if (ans != i) {
tr.link(u[i], i + n);
tr.link(v[i], i + n);
}
}
}
| Env | Name | Status | Elapsed | Memory |
|---|---|---|---|---|
| g++ | example_00 |
|
4 ms | 4 MB |
| g++ | hack_decreasing_00 |
|
559 ms | 82 MB |
| g++ | max_random_00 |
|
1926 ms | 82 MB |
| g++ | max_random_01 |
|
410 ms | 58 MB |
| g++ | max_random_02 |
|
950 ms | 58 MB |
| g++ | max_random_03 |
|
1942 ms | 82 MB |
| g++ | max_random_04 |
|
1921 ms | 82 MB |
| g++ | max_random_05 |
|
404 ms | 58 MB |
| g++ | max_random_06 |
|
938 ms | 58 MB |
| g++ | max_random_07 |
|
410 ms | 58 MB |
| g++ | max_random_08 |
|
401 ms | 58 MB |
| g++ | max_random_09 |
|
1920 ms | 82 MB |
| g++ | random_00 |
|
482 ms | 44 MB |
| g++ | random_01 |
|
403 ms | 48 MB |
| g++ | random_02 |
|
1526 ms | 55 MB |
| g++ | random_03 |
|
796 ms | 54 MB |
| g++ | random_04 |
|
40 ms | 22 MB |
| clang++ | example_00 |
|
4 ms | 4 MB |
| clang++ | hack_decreasing_00 |
|
562 ms | 82 MB |
| clang++ | max_random_00 |
|
2085 ms | 82 MB |
| clang++ | max_random_01 |
|
432 ms | 58 MB |
| clang++ | max_random_02 |
|
1036 ms | 58 MB |
| clang++ | max_random_03 |
|
2004 ms | 82 MB |
| clang++ | max_random_04 |
|
2040 ms | 82 MB |
| clang++ | max_random_05 |
|
441 ms | 58 MB |
| clang++ | max_random_06 |
|
1025 ms | 58 MB |
| clang++ | max_random_07 |
|
434 ms | 58 MB |
| clang++ | max_random_08 |
|
438 ms | 58 MB |
| clang++ | max_random_09 |
|
2039 ms | 82 MB |
| clang++ | random_00 |
|
506 ms | 44 MB |
| clang++ | random_01 |
|
423 ms | 48 MB |
| clang++ | random_02 |
|
1629 ms | 55 MB |
| clang++ | random_03 |
|
837 ms | 54 MB |
| clang++ | random_04 |
|
41 ms | 22 MB |