結果
| 問題 |
No.529 帰省ラッシュ
|
| コンテスト | |
| ユーザー |
はまやんはまやん
|
| 提出日時 | 2017-06-10 13:23:03 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 7,440 bytes |
| コンパイル時間 | 3,175 ms |
| コンパイル使用メモリ | 208,496 KB |
| 実行使用メモリ | 59,880 KB |
| 最終ジャッジ日時 | 2024-09-24 15:32:38 |
| 合計ジャッジ時間 | 10,858 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 1 WA * 12 RE * 5 |
ソースコード
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
//---------------------------------------------------------------------------------------------------
template<int NV> struct UnionFind {
int par[NV], cnt[NV]; UnionFind() { rep(i, 0, NV) par[i] = i, cnt[i] = 1; }
int operator[](int x) { return par[x] == x ? x : par[x] = operator[](par[x]); }
void operator()(int x, int y) { x = operator[](x); y = operator[](y);
if (x != y) par[x] = y, cnt[y] += cnt[x];}}; // xをyにくっつける
struct SCC_BI {
int NV = 0, time; vector<vector<int> > E; vector<int> ord, llink, inin;
stack<int> roots, S; vector<int> M, ART; vector<vector<int> > SC; vector<pair<int, int> > BR;
void init(int NV) { this->NV = NV; E.clear(); E.resize(NV); }
void add_edge(int x, int y) { assert(NV); E[x].push_back(y); E[y].push_back(x); }
void dfs(int cur, int pre) { int art = 0, conn = 0, i, se = 0;ord[cur] = llink[cur] = ++time;
S.push(cur); inin[cur] = 1; roots.push(cur);rep(i, 0, E[cur].size()) {int tar = E[cur][i];
if (ord[tar] == 0) {conn++; dfs(tar, cur);llink[cur] = min(llink[cur], llink[tar]);
art += (pre != -1 && ord[cur] <= llink[tar]);
if (ord[cur]<llink[tar]) BR.push_back(make_pair(min(cur, tar), max(cur, tar)));}
else if (tar != pre || se) {llink[cur] = min(llink[cur], ord[tar]);
while (inin[tar] && ord[roots.top()]>ord[tar]) roots.pop();}else se++;}
if (cur == roots.top()) {SC.push_back(vector<int>());while (1) {
i = S.top(); S.pop(); inin[i] = 0;SC.back().push_back(i);M[i] = SC.size() - 1;
if (i == cur) break;}sort(SC.back().begin(), SC.back().end());roots.pop();}
if (art || (pre == -1 && conn>1)) ART.push_back(cur);}
void scc() {
SC.clear(), BR.clear(), ART.clear(), M.resize(NV); ord.clear(), llink.clear(), inin.clear();
time = 0;ord.resize(NV); llink.resize(NV); inin.resize(NV);
for (int i = 0; i<NV; i++) if (!ord[i]) dfs(i, -1);
sort(BR.begin(), BR.end()); sort(ART.begin(), ART.end());}};
struct HLDecomposition {
vector<set<int>> g;
// vid : id -> vid head, heavy, parent : unknown
// depth : id -> depth inv : vid -> id
vector<int> vid, head, heavy, parent, depth, inv;
HLDecomposition(int n) : g(n), vid(n, -1), head(n), heavy(n, -1), parent(n), depth(n), inv(n) {}
void add(int u, int v) { g[u].insert(v); g[v].insert(u); }
void build(int root) { dfs(root, -1); bfs(); }
int dfs(int curr, int prev) { parent[curr] = prev; int sub = 1, max_sub = 0;
for (int next : g[curr]) if (next != prev) { depth[next] = depth[curr] + 1;
int sub_next = dfs(next, curr); sub += sub_next;
if (max_sub < sub_next) max_sub = sub_next, heavy[curr] = next; }return sub;}
void bfs() { int k = 0; queue<int> q({ 0 }); while (!q.empty()) { int h = q.front(); q.pop();
for (int i = h; i != -1; i = heavy[i]) {vid[i] = k++; inv[vid[i]] = i; head[i] = h;
for (int j : g[i]) if (j != parent[i] && j != heavy[i]) q.push(j);}}}
void foreach(int u, int v, function<void(int, int)> f) {
if (vid[u] > vid[v]) swap(u, v); f(max(vid[head[v]], vid[u]), vid[v]);
if (head[u] != head[v]) foreach(u, parent[head[v]], f);}
int ancestor(int u, int d) { while (true) { if (depth[head[u]] > depth[u] - d) {
d -= depth[u] - depth[head[u]] + 1; if (head[u] == 0) return 0; u = parent[head[u]];}
else return inv[vid[u] - d];} } // uのd個上の頂点を返す(無いなら0)
int lca(int u, int v) { if (vid[u] > vid[v]) swap(u, v); if (head[u] == head[v]) return u;
return lca(u, parent[head[v]]); }
int distance(int u, int v) { return depth[u] + depth[v] - 2 * depth[lca(u, v)]; }};
#define def make_pair(-1, -1)
template<class V, int NV> struct SegTree {
V comp(V l, V r) { return max(l,r); };
vector<V> val; SegTree() { val = vector<V>(NV * 2, def); }
V get(int l, int r) { //[l,r]
if (l > r) return def;
l += NV; r += NV + 1; V ret = def;
while (l < r) { if (l & 1) ret = comp(ret, val[l++]); if (r & 1) ret = comp(ret, val[--r]); l /= 2; r /= 2; }
return ret;
}
void update(int i, V v) { i += NV; val[i] = v; while (i>1) i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]); }
void add(int i, V v) { update(i, val[i + NV] + v); }
};
/*---------------------------------------------------------------------------------------------------
∧_∧
∧_∧ (´<_` ) Welcome to My Coding Space!
( ´_ゝ`) / ⌒i
/ \ | |
/ / ̄ ̄ ̄ ̄/ |
__(__ニつ/ _/ .| .|____
\/____/ (u ⊃
---------------------------------------------------------------------------------------------------*/
int N, M, Q;
vector<int> E[101010];
SCC_BI scc;
UnionFind<101010> uf;
SegTree<pair<int, int>, 101010> st;
priority_queue<int> que[101010];
//---------------------------------------------------------------------------------------------------
int ans_i = -1;
void _main() {
cin >> N >> M >> Q;
scc.init(N);
rep(i, 0, M) {
int a, b;
cin >> a >> b;
a--; b--;
E[a].push_back(b);
E[b].push_back(a);
scc.add_edge(a, b);
}
scc.scc();
for (auto p : scc.SC) rep(i, 1, p.size()) uf(p[0], p[i]);
/*for (auto p : scc.SC) {
printf("<%d> ", uf[p[0]]);
rep(i, 0, p.size()) printf("%d ", p[i]);
printf("\n");
}*/
HLDecomposition hld(N);
rep(i, 0, N) for (int j : E[i]) {
int a = uf[i];
int b = uf[j];
if (a != b) hld.add(a, b);
}
hld.build(uf[0]);
rep(i, 0, N) st.update(i, { -1, -1 });
rep(q, 0, Q) {
int a, b, c; cin >> a >> b >> c;
if (a == 1) {
b = hld.vid[uf[b - 1]];
if (que[b].empty() || que[b].top() < c) {
que[b].push(c);
st.update(b, { c, b });
}
} else {
b = uf[b - 1];
c = uf[c - 1];
//printf("?? %d -> %d\n", b, c);
int lca = hld.lca(b, c);
ans_i = -1;
hld.foreach(lca, b, [](int x, int y) {
//printf(") %d %d\n", x, y);
auto p = st.get(x, y);
if (0 <= p.first) {
if (ans_i < 0) ans_i = p.second;
else if (st.get(ans_i, ans_i) < p) ans_i = p.second;
}
});
hld.foreach(lca, c, [](int x, int y) {
//printf("] %d %d ]\n", x, y);
auto p = st.get(x, y);
if (0 <= p.first) {
if (ans_i < 0) ans_i = p.second;
else if (st.get(ans_i, ans_i) < p) ans_i = p.second;
}
});
if (ans_i < 0) {
printf("-1\n");
} else {
auto p = st.get(ans_i, ans_i);
printf("%d\n", p.first);
que[ans_i].pop();
if (que[ans_i].empty()) st.update(ans_i, { -1, -1 });
else st.update(ans_i, { que[ans_i].top(), ans_i });
}
}
}
}
はまやんはまやん