比赛 |
CSP2023-S模拟赛 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
坡伊踹 |
最终得分 |
100 |
用户昵称 |
usr10086 |
运行时间 |
6.336 s |
代码语言 |
C++ |
内存使用 |
93.75 MiB |
提交时间 |
2023-10-17 21:42:57 |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
ifstream fin("poitry.in");
ofstream fout("poitry.out");
#define cin fin
#define cout fout
#define int long long
const int N = 2e5 + 10, LOGN = 19;
struct E
{
int to, v;
};
vector<E> g[N];
int n, q;
int a[N], dep[N], fa[N][LOGN], apdis[N], andis[N], apd_min[N][LOGN], and_min[N][LOGN], mna[N][LOGN], dis[N];
void bfs(int r)
{
queue<int> q;
q.push(r); dep[r] = 1, mna[r][0] = a[r], andis[r] = a[r]-dis[r], apdis[r] = a[r]+dis[r], apd_min[r][0] = apdis[r], and_min[r][0] = andis[r], dis[r] = 0;
while (!q.empty())
{
int k = q.front(); q.pop();
for (E e : g[k])
{
int to = e.to, v = e.v;
if (dep[to]) continue;
dep[to] = dep[k]+1, fa[to][0] = k, dis[to] = dis[k] + v;
apdis[to] = a[to]+dis[to], andis[to] = a[to]-dis[to];
mna[to][0] = a[to], apd_min[to][0] = apdis[to], and_min[to][0] = andis[to];
for (int i = 1; i < LOGN; i++)
fa[to][i] = fa[fa[to][i-1]][i-1], mna[to][i] = min(mna[to][i-1], mna[fa[to][i-1]][i-1]), apd_min[to][i] = min(apd_min[to][i-1], apd_min[fa[to][i-1]][i-1]), and_min[to][i] = min(and_min[to][i-1], and_min[fa[to][i-1]][i-1]);
q.push(to);
}
}
}
int lca(int u, int v)
{
if (dep[u] < dep[v]) swap(u, v);
for (int i = LOGN-1; ~i; i--)
if (dep[fa[u][i]] >= dep[v]) u = fa[u][i];
if (u == v) return u;
for (int i = LOGN-1; ~i; i--)
if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
return fa[u][0];
}
int min_and(int x, int k)
{
int res = LLONG_MAX;
for (int i = LOGN-1; ~i; i--)
if ((k >> i) & 1) res = min(res, and_min[x][i]), x = fa[x][i];
return min(res, andis[x]);
}
signed main()
{
cin >> n >> q;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1, u, v, w; i < n; i++) cin >> u >> v >> w, g[u].push_back({v, w}), g[v].push_back({u, w});
bfs(1);
while (q--)
{
int u, v;
cin >> u >> v;
int x = u, y = v;
int ac = lca(u, v);
int l1 = dep[u] - dep[ac] + 1, l2 = dep[v] - dep[ac], len = l1 + l2;
{
int tmp = u, cur = LLONG_MAX, amin = LLONG_MAX;
for (int i = LOGN-1; ~i; i--)
if (dep[fa[tmp][i]] >= dep[ac] && min({cur, apd_min[tmp][i], apdis[fa[tmp][i]]}) > dis[u]) amin = min(amin, mna[tmp][i]), cur = min(cur, apd_min[tmp][i]), tmp = fa[tmp][i];
if (tmp != ac)
{
amin = min({amin, a[tmp], max(dis[x] - dis[fa[tmp][0]], a[fa[tmp][0]])});
cout << amin << '\n';
continue;
}
}
// cout << x << "***" << y << endl;
// search 2
int up = l2, tmp = v;
for (int i = LOGN-1; ~i; i--)
if ((1<<i) <= up && min_and(fa[tmp][i], up - (1<<i)) <= dis[u]-2*dis[ac]) tmp = fa[tmp][i], up -= (1<<i);
int amin = LLONG_MAX, bcon = max(dis[x] + dis[tmp] - 2*dis[ac], a[tmp]);
for (int i = LOGN-1; ~i; i--)
if (dep[fa[x][i]] >= dep[ac]) amin = min(amin, mna[x][i]), x = fa[x][i];
amin = min({ amin, a[ac] });
if (up) tmp = fa[tmp][0], up--;
for (int i = LOGN-1; ~i; i--)
if ((up >> i) & 1) amin = min(amin, mna[tmp][i]), tmp = fa[tmp][i];
cout << min(amin, bcon) << '\n';
}
}