結果
問題 | No.529 帰省ラッシュ |
ユーザー | m_tsubasa |
提出日時 | 2020-06-04 10:38:39 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 6,320 bytes |
コンパイル時間 | 3,220 ms |
コンパイル使用メモリ | 235,168 KB |
実行使用メモリ | 47,496 KB |
最終ジャッジ日時 | 2024-11-28 03:14:58 |
合計ジャッジ時間 | 13,140 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 3 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | WA | - |
testcase_05 | WA | - |
testcase_06 | WA | - |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | AC | 492 ms
32,480 KB |
testcase_13 | AC | 434 ms
47,496 KB |
testcase_14 | AC | 581 ms
35,840 KB |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | AC | 621 ms
45,236 KB |
testcase_18 | AC | 638 ms
45,688 KB |
testcase_19 | WA | - |
ソースコード
#include <bits/stdc++.h> using namespace std; // 0-indexed template <class T> struct SegmentTree { // a,b,c: T, e:T(unit) // abc = (ab)c = a(bc) // ae = ea = a typedef function<T(T, T)> F; int n; F f; T unit; vector<T> dat; SegmentTree(){}; SegmentTree(int newn, F f, T t) : f(f), unit(t) { init(newn); } SegmentTree(const vector<T> &v, F f, T t) : f(f), unit(t) { int _n = v.size(); init(v.size()); for (int i = 0; i < _n; ++i) dat[n + i] = v[i]; for (int i = n - 1; i; --i) dat[i] = f(dat[i << 1], dat[(i << 1) | 1]); } void init(int newn) { n = 1; while (n < newn) n <<= 1; dat.assign(n << 1, unit); } // "go up" process void update(int k, T newdata) { dat[k += n] = newdata; while (k >>= 1) { dat[k] = f(dat[(k << 1) | 0], dat[(k << 1) | 1]); } } // [a,b) T query(int a, int b) { T vl = unit, vr = unit; for (int l = a + n, r = b + n; l < r; l >>= 1, r >>= 1) { if (l & 1) vl = f(vl, dat[l++]); if (r & 1) vr = f(dat[--r], vr); } return f(vl, vr); } }; struct HeavyLightDecomposition { int root; vector<vector<int>> g; vector<int> sz, par, dep, in, out, head; HeavyLightDecomposition(int n = 1, int _root = 0) : root(_root), g(n), sz(n), par(n), dep(n), in(n), out(n), head(n) {} HeavyLightDecomposition(const vector<vector<int>> &_g, const int _root = 0) : root(_root), g(_g), sz(_g.size()), par(_g.size()), dep(_g.size()), in(_g.size()), out(_g.size()), head(_g.size()) { build(); } void add(int a, int b) { g[a].push_back(b); g[b].push_back(a); } void build() { dfs_sz(root, -1, 0); int t = 0; dfs_hld(root, -1, t); } void dfs_sz(int now, int bf, int d) { dep[now] = d; par[now] = bf; sz[now] = 1; if (g[now].size() && g[now][0] == bf) swap(g[now][0], g[now].back()); for (auto &to : g[now]) { if (to == bf) continue; dfs_sz(to, now, d + 1); sz[now] += sz[to]; if (sz[g[now][0]] < sz[to]) swap(g[now][0], to); } } void dfs_hld(int now, int bf, int &t) { in[now] = t++; for (auto &to : g[now]) { if (to == bf) continue; head[to] = (g[now][0] == to ? head[now] : to); dfs_hld(to, now, t); } out[now] = t; } int lca(int x, int y) { for (;; y = par[head[y]]) { if (in[x] > in[y]) swap(x, y); if (head[x] == head[y]) return x; } } int chil(int x, int y) { return dep[x] < dep[y] ? y : x; } //[l,r) template <typename F> void for_each(int x, int y, const F &f) { for (;; y = par[head[y]]) { if (in[x] > in[y]) swap(x, y); f(max(in[head[y]], in[x]), in[y] + 1); if (head[x] == head[y]) return; } } //[l,r) template <typename F> void for_eachedge(int x, int y, const F &f) { while (1) { if (in[x] > in[y]) swap(x, y); if (head[x] != head[y]) { f(in[head[y]], in[y] + 1); y = par[head[y]]; } else { if (x != y) f(in[x] + 1, in[y] + 1); break; } } } template <typename T, typename F> void update(int node, T x, const F &f) { f(in[node], x); f(out[node], -x); // laze pattern // f(in[node], out[node], x); } }; // TwoEdgeConnectedComponents + LowLink struct TwoEdgeConnectedComponents { int n; vector<vector<int>> g; vector<int> ord, low, articulation, id; vector<bool> used; using P = pair<int, int>; vector<P> bridge; TwoEdgeConnectedComponents(int _n = 1) : n(_n), g(n) {} TwoEdgeConnectedComponents(vector<vector<int>> &_g) : n(_g.size()), g(_g) { lowlinkbuild(); } bool add(int from, int to) { g[from].push_back(to); g[to].push_back(from); return 1; } void lowlinkbuild() { ord.assign(n, -1); low.assign(n, -1); int k = 0; for (int i = 0; i < n; ++i) if (ord[i] < 0) lowlinkdfs(i, -1, k); } void lowlinkdfs(int now, int par, int &k) { ord[now] = low[now] = k++; bool ch = 0; // articulation int cnt = 0; for (auto &to : g[now]) if (ord[to] < 0) { ++cnt; lowlinkdfs(to, now, k); low[now] = min(low[now], low[to]); ch |= ~par && low[to] >= ord[now]; // articulation if (ord[now] < low[to]) bridge.emplace_back(min(now, to), max(now, to)); // bridge } else if (to != par) low[now] = min(low[now], ord[to]); ch |= par == -1 && cnt > 1; // articulation if (ch) articulation.push_back(now); // articulation } vector<vector<int>> build() { id.assign(n, -1); int k = 0; for (int i = 0; i < n; ++i) if (id[i] < 0) dfs(i, -1, k); vector<vector<int>> res(k); for (auto &e : bridge) { int x = id[e.first], y = id[e.second]; res[x].push_back(y); res[y].push_back(x); } return res; } void dfs(int now, int par, int &k) { if (~par && ord[par] >= low[now]) id[now] = id[par]; else id[now] = k++; for (auto &to : g[now]) if (id[to] < 0) dfs(to, now, k); } inline int operator[](const int &k) { return (id.at(k)); } }; using P = pair<long long, long long>; long long n, m, q; TwoEdgeConnectedComponents tecc; SegmentTree<P> seg; HeavyLightDecomposition hld; vector<vector<int>> g; vector<priority_queue<long long>> lst; int main() { cin >> n >> m >> q; g.resize(n); for (int i = 0; i < m; ++i) { int a, b; cin >> a >> b; g[--a].push_back(--b); g[b].push_back(a); } tecc = TwoEdgeConnectedComponents(g); hld = HeavyLightDecomposition(tecc.build()); lst.resize(n); auto f = [](P l, P r) { return max(l, r); }; seg = SegmentTree<P>(n, f, P(-1, -1)); for (int i = 0; i < q; ++i) { int a, b, c; cin >> a >> b >> c; if (a == 1) { int x = tecc[--b]; lst[x].push(c); seg.update(x, P(lst[x].top(), x)); } else { int x = tecc[--b], y = tecc[--c]; P res(-1, -1); auto func = [&](int l, int r) { res = max(res, seg.query(l, r)); }; hld.for_each(x, y, func); cout << res.first << endl; if (res.first >= 0) { x = res.second; lst[x].pop(); long long num = -1; if (lst[x].size()) num = lst[x].top(); seg.update(x, P(num, x)); } } } return 0; }