1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #define MAXN 100010 int rmq[MAXN * 2], F[MAXN * 2], P[MAXN * 2], cnt, dis[MAXN]; struct SparseTable { int LOG[2 * MAXN]; int dp[2 * MAXN][20]; inline void init(int n) { LOG[0] = -1; for (register int i = 1; i <= n; i++) LOG[i] = LOG[i >> 1] + 1, dp[i][0] = i; for (register int j = 1; j <= LOG[n]; j++) for (register int i = 1; i + (1 << j) - 1 <= n; i++) dp[i][j] = rmq[dp[i][j - 1]] < rmq[dp[i + (1 << (j - 1))][j - 1]] ? dp[i][j - 1] : dp[i + (1 << (j - 1))][j - 1]; } inline int query(int a, int b) { if (a > b) swap(a, b); register int k = LOG[b - a + 1]; return rmq[dp[a][k]] <= rmq[dp[b - (1 << k) + 1][k]] ? dp[a][k] : dp[b - (1 << k) + 1][k]; } }; struct Node { int v, w; Node() {} Node(int v, int w) : v(v), w(w) {} }; vector<Node> e[MAXN << 1]; inline void addEdge(int u, int v, int w) { e[u].push_back(Node(v, w)), e[v].push_back(Node(u, w)); } void dfs(int u, int pre, int dep) { F[++cnt] = u, rmq[cnt] = dep, P[u] = cnt; for (register int i = 0, v; i < e[u].size(); ++i) { v = e[u][i].v; if (v == pre) continue; dis[v] = dis[u] + e[u][i].w; dfs(v, u, dep + 1); F[++cnt] = u, rmq[cnt] = dep; } } SparseTable st; inline void lcaInit(int root, int n) { cnt = 0; dfs(root, root, 0); st.init((n << 1) - 1); } inline int lcaQuery(int u, int v) { return F[st.query(P[u], P[v])]; }
|