結果
問題 | No.529 帰省ラッシュ |
ユーザー |
|
提出日時 | 2021-01-02 22:35:53 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
RE
|
実行時間 | - |
コード長 | 11,793 bytes |
コンパイル時間 | 2,977 ms |
コンパイル使用メモリ | 237,628 KB |
最終ジャッジ日時 | 2025-01-17 09:10:12 |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 9 RE * 8 MLE * 1 |
ソースコード
#include <bits/stdc++.h>using namespace std;/*^ debug */template <typename A, typename B> string to_string(pair<A, B> p);template <typename A, typename B, typename C> string to_string(tuple<A, B, C> p);template <typename A, typename B, typename C, typename D> string to_string(tuple<A, B, C, D> p);string to_string(const string& s) { return '"' + s + '"'; }string to_string(const char* s) { return to_string((string) s); }string to_string(bool b) { return (b ? "true" : "false"); }string to_string(vector<bool> v) {bool first = true;string res = "{";for (int i = 0; i < static_cast<int>(v.size()); i++) {if (!first) { res += ", "; }first = false;res += to_string(v[i]);}res += "}";return res;}template <size_t N>string to_string(bitset<N> v) {string res = "";for (size_t i = 0; i < N; i++) { res += static_cast<char>('0' + v[i]); }return res;}template <typename A>string to_string(A v) {bool first = true;string res = "{";for (const auto &x : v) {if (!first) { res += ", "; }first = false;res += to_string(x);}res += "}";return res;}template <typename A, typename B>string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }template <typename A, typename B, typename C>string to_string(tuple<A, B, C> p) { return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")"; }template <typename A, typename B, typename C, typename D>string to_string(tuple<A, B, C, D> p) { return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " +to_string(get<3>(p)) + ")"; }void debug_out() { cerr << endl; }template <typename Head, typename... Tail>void debug_out(Head H, Tail... T) { cerr << " " << to_string(H); debug_out(T...); }#ifdef LOCAL#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)#else#define debug(...) 42#endif/* debug $*//*^ vector extensions */template<typename T>T concat(initializer_list<T> lists) {T a;for (auto &l : lists) a.insert(a.end(), l.begin(), l.end());return a;}template<typename T, size_t sz>struct _Matrix_type { typedef vector<typename _Matrix_type<T, sz - 1>::type> type; };template<typename T>struct _Matrix_type<T, 1> { typedef T type; };template<typename T>struct _Matrix {static auto build(size_t s) { return vector<T>(s); }template<typename ...Args>static auto build(size_t f, Args... args) {return vector<typename _Matrix_type<T, 1 + sizeof...(args)>::type>(f, _Matrix<T>::build(args...));}};template<typename T, typename... Args>auto buildMatrix(Args... args) { return _Matrix<T>::build(args...); }/* vector extensions $*//*^ generic definitions */template<typename F>struct _RecurFun : F {_RecurFun(F&& f) : F(forward<F>(f)) {}template<typename... Args>decltype(auto) operator()(Args&&... args) const { return F::operator()(*this, forward<Args>(args)...); }};template<typename F>decltype(auto) RecurFun(F&& f) { return _RecurFun<F> { forward<F>(f) }; }/* generic definitions $*/template<typename Elem, typename Tag>struct Segt {vector<Tag> tag;vector<Elem> dat;Segt(int n) : tag(4 * n), dat(4 * n) {function<void(int, int, int)> build = [&](int lb, int rb, int t) {tag[t].lb = dat[t].lb = lb;tag[t].rb = dat[t].rb = rb;if (rb - lb == 1) return;build(lb, lb + rb >> 1, t << 1);build(lb + rb >> 1, rb, t << 1 | 1);dat[t] = dat[t << 1] + dat[t << 1 | 1];};build(0, n, 1);}void push(int k) {if (tag[k].isNull()) return;for (int c = 0; c < 2; ++c) {tag[k << 1 | c] = tag[k << 1 | c] + tag[k];dat[k << 1 | c] = dat[k << 1 | c] + tag[k];}int l = tag[k].lb, r = tag[k].rb;tag[k] = Tag();tag[k].lb = l;tag[k].rb = r;}void update(Tag t, int ql, int qr, int k = 1) {int lb = dat[k].lb;int rb = dat[k].rb;if (qr <= lb || rb <= ql) return;if (ql <= lb && rb <= qr) {tag[k] = tag[k] + t;dat[k] = dat[k] + t;return;}push(k);update(t, ql, qr, k << 1);update(t, ql, qr, k << 1 | 1);dat[k] = dat[k << 1] + dat[k << 1 | 1];}Elem query(int ql, int qr, int k = 1) {int lb = dat[k].lb;int rb = dat[k].rb;if (qr <= lb || rb <= ql) return Elem(lb, rb);if (ql <= lb && rb <= qr) return dat[k];push(k);return query(ql, qr, k << 1) + query(ql, qr, k << 1 | 1);}};struct Elem {int lb, rb;int maxv;int maxi;Elem(int _lb = -1, int _rb = -1) : lb(_lb), rb(_rb) {maxv = 0;maxi = -1;}Elem(int _lb, int _rb, int _maxv, int _maxi) : lb(_lb), rb(_rb) {maxv = _maxv;maxi = _maxi;}friend Elem operator+(const Elem &a, const Elem &b) {// assert(a.rb == b.lb);return Elem(a.lb,b.rb,max(a.maxv, b.maxv),a.maxv > b.maxv ? a.maxi : b.maxi);}friend Elem operator-(const Elem &a, const Elem &b) {// assert(a.rb == b.lb);return Elem(a.lb,b.rb,max(a.maxv, b.maxv),a.maxv > b.maxv ? a.maxi : b.maxi);}};struct Tag {int lb, rb;int setv;int seti;Tag(int _setv = -1, int _seti = -1, int _lb = -1, int _rb = -1) : lb(_lb), rb(_rb) {setv = _setv;seti = _seti;}bool isNull() const { return setv == -1; }Tag operator+() { return *this; }Tag operator-() { return Tag(); }friend Tag operator+(Tag t, Tag tup) {if (tup.isNull()) return t;if (t.isNull()) return tup.lb = t.lb, tup.rb = t.rb, tup;t.setv = tup.setv;t.seti = tup.seti;return t;}friend Elem operator+(Elem e, const Tag &t) {if (t.isNull()) return e;e.maxv = t.setv;e.maxi = t.seti;return e;}};struct LCA {vector<int> dpt;vector<vector<int>> par;LCA() {}LCA(const vector<vector<int>> &g, int root = 0) {int n = g.size();int lgn = 32 - __builtin_clz(n);dpt.resize(n);par.assign(lgn, vector<int>(n, -1));function<void(int, int)> dfs = [&](int u, int fa) {for (int v : g[u]) if (v != fa) {dpt[v] = dpt[u] + 1;par[0][v] = u;dfs(v, u);}};dfs(root, -1);for (int i = 0; i + 1 < lgn; ++i) {for (int u = 0; u < n; ++u) {int p = par[i][u];if (~p) par[i + 1][u] = par[i][p];}}}int query(int u, int v) {if (dpt[u] > dpt[v]) swap(u, v);for (int i = par.size() - 1; ~i; --i) if (dpt[v] - dpt[u] >= 1 << i) {v = par[i][v];}if (u == v) return u;for (int i = par.size() - 1; par[0][u] != par[0][v]; --i) {if (par[i][u] != par[i][v]) {u = par[i][u];v = par[i][v];}}assert(par[0][u] == par[0][v]);return par[0][u];}};template<typename Elem, typename Tag>struct HLD {LCA lca;vector<int> par;vector<int> idxInPath;vector<int> belongsToPath;vector<vector<int>> paths;HLD(const vector<vector<int>> &g) {lca = LCA(g, 0);const int n = g.size();idxInPath.resize(n);belongsToPath.resize(n);function<int(int, int)> dfs = [&](int u, int fa) {int size = 1;pair<int, int> maxchsize(0, -1);for (int v : g[u]) if (v != fa) {int chsize = dfs(v, u);size += chsize;maxchsize = max(maxchsize, make_pair(chsize, v));}int heavyNode = maxchsize.second;if (heavyNode == -1) {par.push_back(fa);idxInPath[u] = 0;belongsToPath[u] = paths.size();paths.emplace_back();paths.back().push_back(u);} else {int x = belongsToPath[heavyNode];par[x] = fa;belongsToPath[u] = x;idxInPath[u] = paths[x].size();paths[x].push_back(u);}return size;};dfs(0, -1);}void updatePath(Tag q, int u, int v, vector<Segt<Elem, Tag>> &st) {int w = lca.query(u, v);function<void(Tag, int, int)> _updatePath = [&](Tag w, int p, int q) {int bp = belongsToPath[p];int bq = belongsToPath[q];if (bp == bq) {st[bp].update(w, idxInPath[p], idxInPath[q] + 1);} else {st[bp].update(w, idxInPath[p], paths[bp].size());_updatePath(w, par[bp], q);}};_updatePath(+q, u, w);_updatePath(+q, v, w);_updatePath(-q, w, w);}Elem queryPath(int u, int v, vector<Segt<Elem, Tag>> &st) {int w = lca.query(u, v);function<Elem(int, int)> _queryPath = [&](int p, int q) {int bp = belongsToPath[p];int bq = belongsToPath[q];if (bp == bq) return st[bp].query(idxInPath[p], idxInPath[q] + 1);return st[bp].query(idxInPath[p], paths[bp].size()) + _queryPath(par[bp], q);};return _queryPath(u, w) + _queryPath(v, w) - _queryPath(w, w);}};struct LowLink {vector<vector<int>> g;vector<int> ord, low, par, dsu;int find(int x) { return dsu[x] == x ? x : dsu[x] = find(dsu[x]); };LowLink(const vector<vector<int>> &g, int root) : g(g), ord(g.size()), low(g.size()), par(g.size(), -1) {dsu.assign(g.size(), 0);iota(dsu.begin(), dsu.end(), 0);int cnt = 0;vector<int> vis(g.size());function<void(int, int)> dfs = [&](int u, int fa) {vis[u] = 1;ord[u] = cnt++;low[u] = ord[u];for (auto &v : g[u]) {if (!vis[v]) {dfs(v, u);low[u] = min(low[u], low[v]);par[v] = u;if (low[v] <= ord[u]) dsu[find(u)] = dsu[find(v)];} else if (v != fa) low[u] = min(low[u], ord[v]);}};dfs(root, -1);}};struct Bridges : LowLink {vector<int> bid;vector<pair<int, int>> bridges;vector<vector<int>> reduced;vector<vector<int>> group;Bridges(const vector<vector<int>> &g) : LowLink(g, 0), bid(g.size()) {int cnt = 0;for (int u = 0; u < g.size(); ++u) if (u == LowLink::find(u)) bid[u] = cnt++;for (int u = 0; u < g.size(); ++u) if (u != LowLink::find(u)) bid[u] = bid[LowLink::find(u)];group.resize(cnt);reduced.resize(cnt);for (int u = 0; u < g.size(); ++u) {group[bid[u]].push_back(u);for (int v : g[u]) if (bid[u] != bid[v]) {bridges.push_back(minmax(u, v));reduced[u].push_back(v);reduced[v].push_back(u);}}for (int u = 0; u < cnt; ++u) {sort(reduced[u].begin(), reduced[u].end());reduced[u].erase(unique(reduced[u].begin(), reduced[u].end()), reduced[u].end());}}};int main() {ios::sync_with_stdio(false);int N, M, Q; {cin >> N >> M >> Q;}vector<vector<int>> G(N); {for (int i = 0; i < M; ++i) {int U, V; {cin >> U >> V;--U, --V;}G[U].push_back(V);G[V].push_back(U);}}Bridges bcc(G);HLD<Elem, Tag> hld(bcc.reduced);vector<Segt<Elem, Tag>> segts; {for (auto &p : hld.paths) segts.emplace_back(p.size());}vector<multiset<int>> que(bcc.group.size());for (int _ = 0; _ < Q; ++_) {int P; { cin >> P; }if (P == 1) {int U, W; { cin >> U >> W; --U; }int bu = bcc.bid[U];que[bu].insert(W);hld.updatePath(Tag(*--que[bu].end(), bu), bu, bu, segts);} else if (P == 2) {int S, T; { cin >> S >> T; --S, --T; }int bs = bcc.bid[S];int bt = bcc.bid[T];auto [_l, _r, v, i] = hld.queryPath(bs, bt, segts);if (v) {cout << v << "\n";assert(~i);assert(que[i].size());assert(*--que[i].end() == v);que[i].erase(--que[i].end());int nv = que[i].empty() ? 0 : *--que[i].end();hld.updatePath(Tag(nv, i), i, i, segts);} else cout << "-1\n";}}}