結果
問題 | No.529 帰省ラッシュ |
ユーザー | paruki |
提出日時 | 2017-06-14 12:58:38 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 649 ms / 4,500 ms |
コード長 | 7,029 bytes |
コンパイル時間 | 2,672 ms |
コンパイル使用メモリ | 213,116 KB |
実行使用メモリ | 60,200 KB |
最終ジャッジ日時 | 2024-12-16 07:17:43 |
合計ジャッジ時間 | 10,006 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 7 ms
5,248 KB |
testcase_05 | AC | 8 ms
5,248 KB |
testcase_06 | AC | 8 ms
5,248 KB |
testcase_07 | AC | 7 ms
5,248 KB |
testcase_08 | AC | 393 ms
24,296 KB |
testcase_09 | AC | 402 ms
24,748 KB |
testcase_10 | AC | 480 ms
30,984 KB |
testcase_11 | AC | 489 ms
31,108 KB |
testcase_12 | AC | 344 ms
26,132 KB |
testcase_13 | AC | 395 ms
60,200 KB |
testcase_14 | AC | 399 ms
28,920 KB |
testcase_15 | AC | 649 ms
34,124 KB |
testcase_16 | AC | 637 ms
34,132 KB |
testcase_17 | AC | 477 ms
44,316 KB |
testcase_18 | AC | 463 ms
44,748 KB |
testcase_19 | AC | 463 ms
41,356 KB |
ソースコード
#include "bits/stdc++.h" using namespace std; #define FOR(i,j,k) for(int (i)=(j);(i)<(int)(k);++(i)) #define rep(i,j) FOR(i,0,j) #define each(x,y) for(auto &(x):(y)) #define mp make_pair #define mt make_tuple #define all(x) (x).begin(),(x).end() #define debug(x) cout<<#x<<": "<<(x)<<endl #define smax(x,y) (x)=max((x),(y)) #define smin(x,y) (x)=min((x),(y)) #define MEM(x,y) memset((x),(y),sizeof (x)) #define sz(x) (int)(x).size() #define pb push_back typedef long long ll; typedef pair<int, int> pii; typedef vector<int> vi; typedef vector<ll> vll; class TwoEdgeCC { public: TwoEdgeCC(vector<vector<int> > &G) :V((int)G.size()), now(0), disc(V), low(V) { for (int i = 0; i < V; ++i) { if (!disc[i]) { dfs(G, i, -1); } } if (stk.size()) { tecc.push_back(vector<int>()); do { tecc.back().push_back(stk.top()); stk.pop(); } while (stk.size()); } } vector<pair<int,int> > getBridges() { return move(bridges); } vector<vector<int>> get() { return move(tecc); } private: int V, now; vector<int> disc, low; vector<pair<int,int> > bridges; stack<int> stk; vector<vector<int>> tecc; void dfs(const vector<vector<int> > &G, int u, int parent) { disc[u] = ++now; low[u] = now; stk.push(u); for (int i = 0; i < (int)G[u].size(); ++i) { int v = G[u][i]; if (!disc[v]) { dfs(G, v, u); low[u] = min(low[u], low[v]); if (disc[u] < low[v]) { int x = u, y = v; if (x > y)swap(x, y); bridges.emplace_back(x, y); int w; tecc.push_back(vector<int>()); do { w = stk.top(); tecc.back().push_back(w); stk.pop(); } while (w != v); } } else if (v != parent) { low[u] = min(low[u], disc[v]); } } } }; class HLDecomposition { int cur = 0; void bfs(const vector<vector<int> > &G) { queue<tuple<int, int, int> > que; vector<int> order; que.push(make_tuple(0, -1, 0)); while (!que.empty()) { int u, pre, d; tie(u, pre, d) = que.front(); que.pop(); parent[u] = pre; depth[u] = d; order.push_back(u); for (int v : G[u])if (v != pre) { que.push(make_tuple(v, u, d + 1)); } } reverse(order.begin(), order.end()); for (int u : order) { sub[u] = 1; for (int v : G[u])if (v != parent[u])sub[u] += sub[v]; } } void dfs_stk(const vector<vector<int> > & G) { stack<pair<int, int> > stk; stk.push(make_pair(0, 0)); while (!stk.empty()) { int u, h, pre; tie(u, h) = stk.top(); stk.pop(); head[u] = h; id[u] = cur++; pre = parent[u]; int heavy = -1, maxi = 0; for (int v : G[u]) { if (v != pre && maxi < sub[v]) { maxi = sub[v]; heavy = v; } } for (int v : G[u]) { if (v != pre&&v != heavy) { stk.push(make_pair(v, v)); } } if (heavy != -1)stk.push(make_pair(heavy, h)); } } public: vector<int> parent, depth, sub, id, head; HLDecomposition(const vector<vector<int> > &G) { parent = depth = sub = id = head = vector<int>(G.size()); bfs(G); dfs_stk(G); } /* パス(u, v)を半開区間の集合に変換する。 O(log(|V|)) */ vector<pair<int, int> > goUpToLCA(int u, int v) { vector<pair<int, int> > res; while (true) { if (head[u] == head[v]) { if (depth[u] > depth[v])swap(u, v); res.emplace_back(id[u], id[v] + 1); break; } else { if (depth[head[u]] > depth[head[v]])swap(u, v); res.emplace_back(id[head[v]], id[v] + 1); v = parent[head[v]]; } } return res; } }; template<class Val, class Cmp> class DynamicRMQ { int n; Val init; vector<Val> dat; Cmp cmp; inline Val query(int a, int b, int k, int l, int r) { if (r <= a || b <= l) return init; if (a <= l&&r <= b) return dat[k]; else { Val vl, vr; vl = query(a, b, k << 1, l, (l + r) >> 1); vr = query(a, b, (k << 1) | 1, (l + r) >> 1, r); return cmp(vl, vr) ? vl : vr; } } public: DynamicRMQ() {} DynamicRMQ(int n_, Val init_) :n(1), init(init_) { for (; n<n_; n <<= 1); dat = vector<Val>(n << 1, init); } void update(int k, Val a) { k += n; dat[k] = a; while (k > 1) { k >>= 1; dat[k] = cmp(dat[k << 1], dat[(k << 1) | 1]) ? dat[k << 1] : dat[(k << 1) | 1]; } } Val query(int a, int b) { return query(a, b, 1, 0, n); } }; typedef DynamicRMQ<long long, less<long long> > RMinQ64; typedef DynamicRMQ<long long, greater<long long> > RMaxQ64; typedef DynamicRMQ<int, less<int> > RMinQ32; typedef DynamicRMQ<int, greater<int> > RMaxQ32; int main(){ ios::sync_with_stdio(false); cin.tie(0); int N, M, Q; cin >> N >> M >> Q; vector<vi> G(N); rep(i, M) { int a, b; cin >> a >> b; --a; --b; G[a].push_back(b); G[b].push_back(a); } auto tecc = TwoEdgeCC(G).get(); vi id(N); rep(i, sz(tecc)) { each(j, tecc[i]) { id[j] = i; } } int K = sz(tecc); vector<vi> H(K); rep(i, N)each(j, G[i]) { int u = id[i], v = id[j]; if (u != v) { H[u].push_back(v); } } auto hl = HLDecomposition(H); RMaxQ32 rmq(K, -1); unordered_map<int, int> pos; vector<set<int>> vals(K); while (Q--) { int t, x, y; cin >> t >> x >> y; if (t == 1) { x = hl.id[id[x-1]]; vals[x].insert(y); rmq.update(x, *vals[x].rbegin()); pos[y] = x; } else { x = id[x - 1], y = id[y - 1]; auto path = hl.goUpToLCA(x, y); int ans = -1; each(p, path) { smax(ans, rmq.query(p.first, p.second)); } cout << ans << endl; if (ans != -1) { int p = pos[ans], z = -1; vals[p].erase(ans); if (sz(vals[p]))z = *vals[p].rbegin(); rmq.update(p, z); } } } }