#include <bits/stdc++.h>
using namespace std;
#include "factories.h"
using ll = long long;
namespace {
template <class T>
struct RMQ{
vector<vector<T>> table;
int _n, _lg;
RMQ() = default;
RMQ(vector<T> &v){
_n = v.size(); _lg = log2(_n);
table.assign(_lg + 1, vector<T>(_n));
for (int i = 0; i < _n; i++) table[0][i] = v[i];
for (int j = 1; j <= _lg; j++){
for (int i = 0; i + (1 << j) <= _n; i++){
table[j][i] = min(table[j-1][i], table[j-1][i + (1 << (j-1))]);
}
}
}
T get(int l, int r){
int j = log2(r - l + 1);
return min(table[j][l], table[j][r - (1 << j) + 1]);
}
};
int n;
const ll inf = 1e18;
vector<vector<pair<int, int>>> adj;
vector<pair<int, int>> euler_tour;
vector<ll> dist, d1, d2;
vector<int> tin, tout, firstocc, op;
int timer = 0;
RMQ<pair<int, int>> rmq;
void euler_dfs(int x, int p = -1, int d = 0){
firstocc[x] = euler_tour.size();
euler_tour.emplace_back(d, x);
tin[x] = timer++;
for (auto [k, w]: adj[x]){
if (k == p) continue;
dist[k] = dist[x] + w;
euler_dfs(k, x, d+1);
euler_tour.emplace_back(d, x);
}
tout[x] = timer++;
}
int LCA(int x, int y){
if (firstocc[x] > firstocc[y]) swap(x, y);
return rmq.get(firstocc[x], firstocc[y]).second;
}
ll distance(int x, int y){
return dist[x] + dist[y] - dist[LCA(x, y)] * 2;
}
}
void Init(int N, int A[], int B[], int D[]){
n = N;
adj.resize(n);
tin.resize(n);
tout.resize(n);
firstocc.resize(n);
dist.assign(n, 0);
d1.assign(n, inf);
d2.assign(n, inf);
op.assign(n, 0);
for (int i = 0; i < n-1; i++){
adj[A[i]].emplace_back(B[i], D[i]);
adj[B[i]].emplace_back(A[i], D[i]);
}
euler_dfs(0);
rmq = RMQ<pair<int, int>>(euler_tour);
}
ll Query(int S, int X[], int T, int Y[]){
for (int i = 0; i < S; i++) op[X[i]] = 1;
for (int i = 0; i < T; i++) op[Y[i]] = 2;
vector<int> Z;
for (int i = 0; i < S; i++) Z.push_back(X[i]);
for (int i = 0; i < T; i++) Z.push_back(Y[i]);
sort(Z.begin(), Z.end(), [&](int a, int b){
return tin[a] < tin[b];
});
for (int i = 1; i < S + T; i++){
int lca = LCA(Z[i-1], Z[i]);
if (!op[lca]){
op[lca] = 3;
Z.push_back(lca);
}
}
sort(Z.begin(), Z.end(), [&](int a, int b){
return tin[a] < tin[b];
});
stack<int> parent;
ll res = inf;
for (int i = 0; i < (int)Z.size(); i++){
while (!parent.empty()){
if (tin[parent.top()] <= tin[Z[i]] && tout[Z[i]] <= tout[parent.top()]) break;
int tp = parent.top(); parent.pop();
res = min(res, d1[tp] + d2[tp]);
if (!parent.empty()){
int dt = distance(parent.top(), tp);
d1[parent.top()] = min(d1[parent.top()], d1[tp] + dt);
d2[parent.top()] = min(d2[parent.top()], d2[tp] + dt);
}
}
parent.push(Z[i]);
if (op[Z[i]] == 1) d1[Z[i]] = 0;
if (op[Z[i]] == 2) d2[Z[i]] = 0;
}
while (!parent.empty()){
int tp = parent.top(); parent.pop();
res = min(res, d1[tp] + d2[tp]);
if (!parent.empty()){
int dt = distance(parent.top(), tp);
d1[parent.top()] = min(d1[parent.top()], d1[tp] + dt);
d2[parent.top()] = min(d2[parent.top()], d2[tp] + dt);
}
}
for (auto i: Z) op[i] = 0;
for (auto i: Z) d1[i] = d2[i] = inf;
return res;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
836 KB |
Output is correct |
2 |
Correct |
563 ms |
10752 KB |
Output is correct |
3 |
Correct |
654 ms |
10672 KB |
Output is correct |
4 |
Incorrect |
585 ms |
10664 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
468 KB |
Output is correct |
2 |
Correct |
1230 ms |
233756 KB |
Output is correct |
3 |
Incorrect |
1275 ms |
236128 KB |
Output isn't correct |
4 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
836 KB |
Output is correct |
2 |
Correct |
563 ms |
10752 KB |
Output is correct |
3 |
Correct |
654 ms |
10672 KB |
Output is correct |
4 |
Incorrect |
585 ms |
10664 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |