結果
問題 |
No.529 帰省ラッシュ
|
ユーザー |
|
提出日時 | 2025-03-17 20:51:18 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 580 ms / 4,500 ms |
コード長 | 4,792 bytes |
コンパイル時間 | 3,423 ms |
コンパイル使用メモリ | 230,380 KB |
実行使用メモリ | 81,720 KB |
最終ジャッジ日時 | 2025-03-17 20:51:30 |
合計ジャッジ時間 | 11,181 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 18 |
ソースコード
#include<bits/stdc++.h> #define lowbit(x) x & (-x) #define ls(k) k << 1 #define rs(k) k << 1 | 1 #define fi first #define se second #define ctz(x) __builtin_ctz(x) #define popcnt(x) __builtin_popcount(x) #define open(s1, s2) freopen(s1, "r", stdin), freopen(s2, "w", stdout); using namespace std; typedef __int128 __; typedef long double lb; typedef double db; typedef unsigned long long ull; typedef long long ll; const int N = 2e5 + 10; inline ll read(){ ll x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9'){ if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9'){ x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return x * f; } inline void write(ll x){ if(x < 0){ putchar('-'); x = -x; } if(x > 9) write(x / 10); putchar(x % 10 + '0'); } int n, m, q, op, u, v, cnt, sum; int dfn[N], low[N], fa[N], dep[N], rdfn[N], son[N], siz[N], top[N], id[N]; stack<int> T; vector<pair<int, int>> E[N]; vector<int> G[N]; set<pair<int, int>> S; inline void add(int u, int v, int id){ E[u].push_back({v, id}); } inline void add(int u, int v){ G[u].push_back(v); G[v].push_back(u); } inline void tarjan(int u, int fa){ dfn[u] = low[u] = ++cnt; T.push(u); for(auto t : E[u]){ int v = t.fi, w = t.se; if(w == (fa ^ 1)) continue; if(!dfn[v]){ tarjan(v, w); low[u] = min(low[u], low[v]); } else low[u] = min(low[u], dfn[v]); } if(dfn[u] == low[u]){ ++sum; id[u] = sum; while(T.top() != u){ id[T.top()] = sum; T.pop(); } T.pop(); } } inline void dfs1(int u, int f){ siz[u] = 1; for(auto v : G[u]){ if(v == f) continue; fa[v] = u; dep[v] = dep[u] + 1; dfs1(v, u); siz[u] += siz[v]; if(siz[v] > siz[son[u]]) son[u] = v; } } inline void dfs2(int u, int k){ dfn[u] = ++cnt; rdfn[cnt] = u; top[u] = k; if(!son[u]) return ; dfs2(son[u], k); for(auto v : G[u]){ if(v == fa[u] || v == son[u]) continue; dfs2(v, v); } } namespace Tree{ struct Node{ int l, r; int Max, id; priority_queue<int> S; }X[N << 2]; inline void pushup(int k){ X[k].Max = max(X[k << 1].Max, X[k << 1 | 1].Max); if(X[k << 1].Max == X[k].Max) X[k].id = X[k << 1].id; else X[k].id = X[k << 1 | 1].id; } inline void build(int k, int l, int r){ X[k].l = l, X[k].r = r; X[k].Max = -1; if(l == r){ X[k].id = l; return ; } int mid = (l + r) >> 1; build(k << 1, l, mid); build(k << 1 | 1, mid + 1, r); pushup(k); } inline void update(int k, int i, int v){ if(X[k].l == i && i == X[k].r){ X[k].S.push(v); X[k].Max = X[k].S.top(); // cerr << "now1:" << i << ' ' << X[k].Max << '\n'; return ; } int mid = (X[k].l + X[k].r) >> 1; if(i <= mid) update(k << 1, i, v); else update(k << 1 | 1, i, v); pushup(k); } inline void del(int k, int i){ if(X[k].l == i && i == X[k].r){ // cerr << "Yes " << ' ' << i << ' ' << X[k].S.size() << '\n';; X[k].S.pop(); if(X[k].S.empty()) X[k].Max = -1; else X[k].Max = X[k].S.top(); // cerr << X[k].Max << ' ' << X[k].S.size() << '\n'; return ; } int mid = (X[k].l + X[k].r) >> 1; if(i <= mid) del(k << 1, i); else del(k << 1 | 1, i); pushup(k); } inline pair<int, int> ask(int k, int l, int r){ if(X[k].l == l && r == X[k].r) return {X[k].Max, X[k].id}; int mid = (X[k].l + X[k].r) >> 1; if(r <= mid) return ask(k << 1, l, r); else if(l > mid) return ask(k << 1 | 1, l, r); else{ auto x = ask(k << 1, l, mid), y = ask(k << 1 | 1, mid + 1, r); if(x.fi >= y.fi) return x; else return y; } } }; inline int query(int u, int v){ int Max = -1, id = 0; while(top[u] != top[v]){ if(dep[top[u]] < dep[top[v]]) swap(u, v); auto t = Tree::ask(1, dfn[top[u]], dfn[u]); if(t.fi > Max){ Max = t.fi; id = t.se; } u = fa[top[u]]; } if(dep[u] > dep[v]) swap(u, v); auto t = Tree::ask(1, dfn[u], dfn[v]); if(t.fi > Max){ Max = t.fi; id = t.se; } // cerr << id << '\n'; if(id) Tree::del(1, id); return Max; } int main(){ n = read(), m = read(), q = read(); for(int u, v, i = 1; i <= m; ++i){ u = read(), v = read(); add(u, v, i << 1); add(v, u, i << 1 | 1); } for(int i = 1; i <= n; ++i) if(!dfn[i]) tarjan(i, 0); for(int u = 1; u <= n; ++u){ for(auto t : E[u]){ int v = t.fi; if(id[u] == id[v] || S.count({id[u], id[v]}) || S.count({id[v], id[u]})) continue; S.insert({id[u], id[v]}); add(id[u], id[v]); } } cnt = 0; dfs1(1, 1); dfs2(1, 1); Tree::build(1, 1, cnt); while(q--){ op = read(), u = read(), v = read(); if(op == 1) Tree::update(1, dfn[id[u]], v); else{ write(query(id[u], id[v])); putchar('\n'); } // cerr << "lst: " << Tree::X[1].id << '\n'; } return 0; }