結果
問題 | No.529 帰省ラッシュ |
ユーザー | はまやんはまやん |
提出日時 | 2017-06-16 16:59:09 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 477 ms / 4,500 ms |
コード長 | 6,418 bytes |
コンパイル時間 | 2,659 ms |
コンパイル使用メモリ | 204,612 KB |
実行使用メモリ | 59,080 KB |
最終ジャッジ日時 | 2024-05-09 16:42:10 |
合計ジャッジ時間 | 9,043 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 6 ms
10,624 KB |
testcase_01 | AC | 6 ms
10,568 KB |
testcase_02 | AC | 6 ms
10,496 KB |
testcase_03 | AC | 5 ms
10,440 KB |
testcase_04 | AC | 9 ms
10,752 KB |
testcase_05 | AC | 9 ms
10,820 KB |
testcase_06 | AC | 9 ms
10,752 KB |
testcase_07 | AC | 8 ms
10,752 KB |
testcase_08 | AC | 330 ms
37,700 KB |
testcase_09 | AC | 323 ms
37,524 KB |
testcase_10 | AC | 391 ms
42,344 KB |
testcase_11 | AC | 397 ms
42,504 KB |
testcase_12 | AC | 239 ms
39,008 KB |
testcase_13 | AC | 279 ms
59,080 KB |
testcase_14 | AC | 316 ms
43,612 KB |
testcase_15 | AC | 474 ms
45,640 KB |
testcase_16 | AC | 477 ms
45,780 KB |
testcase_17 | AC | 454 ms
56,268 KB |
testcase_18 | AC | 465 ms
56,664 KB |
testcase_19 | AC | 435 ms
53,516 KB |
ソースコード
#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(); } //--------------------------------------------------------------------------------------------------- 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; 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(); HLDecomposition hld(N); rep(i, 0, N) for (int j : E[i]) { int a = scc.M[i]; int b = scc.M[j]; if (a != b) hld.add(a, b); } hld.build(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[scc.M[b - 1]]; if (que[b].empty() || que[b].top() < c) st.update(b, { c, b }); que[b].push(c); } else { b = scc.M[b - 1]; c = scc.M[c - 1]; ans_i = -1; hld.foreach(b, c, [](int x, int y) { //printf("] %d %d ]\n", x, y); auto p = st.get(x, y); 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 }); } } } } }