社区讨论
LCA+前缀和 WA#11#15求调
P4427[BJOI2018] 求和参与者 3已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mhjryi7q
- 此快照首次捕获于
- 2025/11/04 07:32 4 个月前
- 此快照最后确认于
- 2025/11/04 07:32 4 个月前
CPP
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
constexpr i64 N = 3e5 + 5, MAXLOG = 18, K = 55, mod = 998244353;
// Graph representation
vector<int> G[N];
i64 dep[N], mul[K], sa[N][K], anc[N][MAXLOG];
i64 ksm(i64 a, i64 b) {
// Fast exponentiation modulo mod
i64 res = 1;
while (b) {
if (b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void dfs(int x, int fa) {
anc[x][0] = fa;
for (int i = 1; i < MAXLOG; ++i) {
anc[x][i] = anc[anc[x][i - 1]][i - 1];
}
for (int y : G[x]) {
if (y != fa) {
dep[y] = dep[x] + 1;
for (int i = 1; i <= 50; i++) {
mul[i] = mul[i - 1] * dep[y] % mod;
}
for (int i = 1; i <= 50; i++) {
sa[y][i] = (sa[x][i] + mul[i]) % mod;
}
dfs(y, x);
}
}
}
int LCA(int x, int y) {
// Find the Lowest Common Ancestor (LCA) of nodes x and y
if (dep[x] < dep[y]) swap(x, y);
for (int i = MAXLOG - 1; i >= 0; --i) {
if (dep[anc[x][i]] >= dep[y]) {
x = anc[x][i];
}
}
if (x == y) return x;
for (int i = MAXLOG - 1; i >= 0; --i) {
if (anc[x][i] != anc[y][i]) {
x = anc[x][i];
y = anc[y][i];
}
}
return anc[x][0];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
// Input number of nodes
int n;
cin >> n;
// Initialize the graph
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
// Start DFS from node 1 (assuming 1 is the root)
mul[0] = 1; // Initialize the multiplier for depth 0
dfs(1, 0);
// Input number of queries
int m;
cin >> m;
// Process each query
while (m--) {
int u, v, k;
cin >> u >> v >> k;
// Find the LCA of u and v
int lca = LCA(u, v);
// Calculate the result using the precomputed powers
i64 res = (sa[u][k] + sa[v][k] - sa[anc[lca][0]][k] - sa[lca][k] + 2 * mod) % mod;
cout << res << '\n';
}
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...