QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#724419 | #8235. Top Cluster | Shunpower | RE | 0ms | 0kb | C++14 | 2.8kb | 2024-11-08 13:04:14 | 2024-11-08 13:04:15 |
answer
#include <bits/stdc++.h>
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
constexpr int N = 5E5 + 1, M = 21;
int n, q, tot, st[N][M], dfn[N], c[N], p[N], maxR;
std::array<int, 2> diameter[N];
i64 d[N];
std::vector<std::array<int, 2>> adj[N];
int get(int x, int y) {
return dfn[x] < dfn[y] ? x : y;
}
void dfs(int x, int fa) {
st[dfn[x] = tot++][0] = fa;
for (auto [v, w] : adj[x]) {
if (v == fa) {
continue;
}
d[v] = d[x] + w;
dfs(v, x);
}
}
int getlca(int u, int v) {
if (u == v) {
return u;
}
if ((u = dfn[u]) > (v = dfn[v])) {
std::swap(u, v);
}
int d = std::__lg(v - u++);
return get(st[u][d], st[v - (1 << d) + 1][d]);
}
i64 dis(int u, int v) {
return d[u] + d[v] - 2 * d[getlca(u, v)];
}
int main() {
freopen("butterfly.in", "r", stdin);
freopen("butterfly.out", "w", stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> q;
for (int i = 0; i < n; ++i) {
p[i] = -1;
}
for (int i = 0; i < n; ++i) {
std::cin >> c[i];
if (c[i] < n) {
p[c[i]] = i;
}
}
for (int i = 1; i < n; ++i) {
int u, v, w;
std::cin >> u >> v >> w;
--u, --v;
adj[u].push_back({v, w});
adj[v].push_back({u, w});
}
dfs(0, 0);
for (int j = 1; j <= std::__lg(n); ++j) {
for (int i = 0; i + (1 << j) <= n; ++i) {
st[i][j] = get(st[i][j - 1], st[i + (1 << j - 1)][j - 1]);
}
}
int d1 = -1, d2 = -1;
for (int i = 0; i < n; ++i) {
if (p[i] == -1) {
maxR = i - 1;
break;
}
int x = p[i];
if (d1 == -1) {
d1 = d2 = x;
} else {
i64 u = dis(x, d1), v = dis(x, d2);
if (u > v) {
std::swap(u, v);
std::swap(d1, d2);
}
if (v > dis(d1, d2)) {
d1 = x;
}
}
diameter[i] = {d1, d2};
}
while (q--) {
int x;
i64 k;
std::cin >> x >> k;
--x;
auto check = [&](int mid) {
if (mid > maxR) {
return false;
}
auto [u, v] = diameter[mid];
return std::max(dis(u, x), dis(v, x)) <= k;
} ;
int l = 0, r = maxR;
while (l < r) {
int mid = (l + r + 1) / 2;
if (check(mid)) {
l = mid;
} else {
r = mid - 1;
}
}
if (!check(l)) {
std::cout << l << "\n";
} else {
std::cout << l + 1 << "\n";
}
}
return 0;
}
詳細信息
Test #1:
score: 0
Dangerous Syscalls
input:
5 4 3 9 0 1 2 1 2 10 3 1 4 3 4 3 3 5 2 3 0 1 0 4 6 4 7