結果

問題 No.529 帰省ラッシュ
ユーザー 0w1
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#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";
}
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0