結果
問題 | No.529 帰省ラッシュ |
ユーザー | はまやんはまやん |
提出日時 | 2017-06-10 13:44:18 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 567 ms / 4,500 ms |
コード長 | 6,991 bytes |
コンパイル時間 | 3,568 ms |
コンパイル使用メモリ | 206,520 KB |
実行使用メモリ | 59,880 KB |
最終ジャッジ日時 | 2024-05-09 16:17:48 |
合計ジャッジ時間 | 11,113 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 8 ms
11,352 KB |
testcase_01 | AC | 8 ms
11,164 KB |
testcase_02 | AC | 7 ms
11,264 KB |
testcase_03 | AC | 7 ms
11,384 KB |
testcase_04 | AC | 10 ms
11,648 KB |
testcase_05 | AC | 11 ms
11,520 KB |
testcase_06 | AC | 10 ms
11,552 KB |
testcase_07 | AC | 10 ms
11,648 KB |
testcase_08 | AC | 400 ms
38,300 KB |
testcase_09 | AC | 386 ms
38,488 KB |
testcase_10 | AC | 476 ms
43,136 KB |
testcase_11 | AC | 492 ms
43,292 KB |
testcase_12 | AC | 292 ms
39,672 KB |
testcase_13 | AC | 298 ms
59,880 KB |
testcase_14 | AC | 364 ms
44,376 KB |
testcase_15 | AC | 563 ms
46,560 KB |
testcase_16 | AC | 567 ms
46,440 KB |
testcase_17 | AC | 529 ms
56,864 KB |
testcase_18 | AC | 529 ms
57,544 KB |
testcase_19 | AC | 530 ms
54,432 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(); } //--------------------------------------------------------------------------------------------------- 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[i], p[0]); /*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) st.update(b, { c, b }); que[b].push(c); } else { b = uf[b - 1]; c = uf[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 }); } } } } }