結果
| 問題 |
No.529 帰省ラッシュ
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2017-08-01 19:17:28 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 253 ms / 4,500 ms |
| コード長 | 3,517 bytes |
| コンパイル時間 | 1,077 ms |
| コンパイル使用メモリ | 93,608 KB |
| 実行使用メモリ | 34,788 KB |
| 最終ジャッジ日時 | 2024-12-16 07:27:35 |
| 合計ジャッジ時間 | 5,224 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 18 |
ソースコード
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
#include <queue>
struct HLD {
std::vector<int> parent, head, vid;
HLD(const std::vector<std::vector<int>> &g) : parent(g.size()), head(g.size()), vid(g.size(), -1) {
int now = 0;
std::vector<int> s(g.size(), 1);
std::function<void(int, int)> dfs = [&](int u, int p) { for (int v : g[u]) if (v != p) dfs(v, u), s[u] += s[v]; };
std::function<void(int, int, int)> dfs2 = [&](int u, int p, int h) {
parent[u] = p;
head[u] = h;
vid[u] = now++;
for (int v : g[u]) if (v != p && s[u] < s[v] * 2) dfs2(v, u, h);
for (int v : g[u]) if (v != p && s[u] >= s[v] * 2) dfs2(v, u, v);
};
dfs(0, -1);
dfs2(0, -1, 0);
}
template<class T>
void foreach(int u, int v, T f) {
while (true) {
if (vid[u] > vid[v]) std::swap(u, v);
if (head[u] == head[v]) {
f(vid[u], vid[v]);
break;
}
f(vid[head[v]], vid[v]);
v = parent[head[v]];
}
}
int lca(int u, int v) {
for (; head[u] != head[v]; v = parent[head[v]]) if (vid[u] > vid[v]) std::swap(u, v);
return vid[u] < vid[v] ? u : v;
}
};
std::vector<int> TECC(const std::vector<std::vector<int>> &g) {
const int n = g.size();
std::vector<int> ord(n, -1), low(n), cid(n), s;
int k = 0;
int c = 0;
std::function<void(int, int)> dfs = [&](int u, int p) {
low[u] = ord[u] = k++;
s.push_back(u);
for (int v : g[u]) {
if (ord[v] == -1) {
dfs(v, u);
low[u] = std::min(low[u], low[v]);
} else if (v != p) low[u] = std::min(low[u], ord[v]);
}
if (p == -1 || ord[p] < low[u]) {
while (true) {
int v = s.back();
s.pop_back();
cid[v] = c;
if (v == u) break;
}
c++;
}
};
for (int i = 0; i < n; i++) {
if (ord[i] == -1) dfs(i, -1);
}
return cid;
}
int main() {
int n, m, q;
std::cin >> n >> m >> q;
std::vector<std::vector<int>> g(n);
for (int i = 0; i < m; i++) {
int u, v;
scanf("%d %d", &u, &v);
u--;
v--;
g[u].push_back(v);
g[v].push_back(u);
}
auto tecc = TECC(g);
int nn = *max_element(tecc.begin(), tecc.end()) + 1;
std::vector<std::vector<int>> gg(nn);
for (int i = 0; i < n; i++) {
for (int j : g[i]) {
if (tecc[i] != tecc[j]) {
gg[tecc[i]].push_back(tecc[j]);
}
}
}
HLD hld(gg);
int N = 1;
while (N < nn) {
N *= 2;
}
std::vector<std::pair<int, int>> rmq(N * 2, std::make_pair(-1, 0));
auto setval = [&](int k, int v, int index) {
k += N;
rmq[k] = { v, index };
while (k > 1) {
k >>= 1;
rmq[k] = std::max(rmq[k * 2], rmq[k * 2 + 1]);
}
};
auto getval = [&](int l, int r) {
std::pair<int, int> ret(-1, 0);
for (l += N, r += N; l < r; l >>= 1, r >>= 1) {
if (l & 1) ret = std::max(ret, rmq[l++]);
if (r & 1) ret = std::max(ret, rmq[--r]);
}
return ret;
};
std::vector<std::priority_queue<int>> qs(nn);
while (q--) {
int t;
scanf("%d", &t);
if (t == 1) {
int u, w;
scanf("%d %d", &u, &w);
u = tecc[u - 1];
if (qs[u].empty() || qs[u].top() < w) {
setval(hld.vid[u], w, u);
}
qs[u].push(w);
} else {
int s, t;
scanf("%d %d", &s, &t);
s = tecc[s - 1];
t = tecc[t - 1];
std::pair<int, int> ans(-1, 0);
hld.foreach(s, t, [&](int l, int r) {
ans = std::max(ans, getval(l, r + 1));
});
if (ans.first != -1) {
qs[ans.second].pop();
if (qs[ans.second].empty()) {
setval(hld.vid[ans.second], -1, ans.second);
} else {
setval(hld.vid[ans.second], qs[ans.second].top(), ans.second);
}
}
printf("%d\n", ans.first);
}
}
}