#ifndef Nhoksocqt1
#include "closing.h"
#endif // Nhoksocqt1
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define sz(x) int((x).size())
#define fi first
#define se second
typedef long long ll;
typedef pair<int, int> ii;
template<class X, class Y>
inline bool maximize(X &x, const Y &y) {return (x < y ? x = y, 1 : 0);}
template<class X, class Y>
inline bool minimize(X &x, const Y &y) {return (x > y ? x = y, 1 : 0);}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int Random(int l, int r) {
return uniform_int_distribution<int>(l, r)(rng);
}
const bool isMultiTest = 0;
const int MAXN = 200005;
vector<ii> adj[MAXN];
ll fen_dist[3 * MAXN], fen_l[3 * MAXN], fen_h[3 * MAXN];
ll dist_l[MAXN], dist_h[MAXN], maxSum;
int pa[MAXN], numNode, x_node, y_node;
bool inPath[MAXN];
void dfs_init(int u, int p, ll dist_from_root, ll dist[], int par[]) {
par[u] = p;
dist[u] = dist_from_root;
for (int it = 0; it < sz(adj[u]); ++it) {
int v(adj[u][it].fi), w(adj[u][it].se);
if(v != par[u])
dfs_init(v, u, dist_from_root + w, dist, par);
}
}
typedef pair<ll, int> pli;
struct Data {
ll dif, val_l;
int node;
};
vector<Data> sorted_diff;
vector<pli> sorted_val;
void modify(ll fen[], int i, ll v) {
for (; i <= 3 * numNode; i += i & -i)
fen[i] += v;
}
ll get(ll fen[], int i) {
ll res(0);
for (; i > 0; i -= i & -i)
res += fen[i];
return res;
}
int walkOnFen(ll fen[], ll maxSum) {
int i(0);
for (int j = 31 - __builtin_clz(3 * numNode); j >= 0; --j) {
if(i + (1 << j) <= 3 * numNode && maxSum >= fen[i + (1 << j)]) {
i += (1 << j);
maxSum -= fen[i];
}
}
return i;
}
int getSumOptLeft(ll maxSum) {
int idx = walkOnFen(fen_dist, maxSum);
ll max_sum = get(fen_dist, idx);
int get_l = get(fen_l, idx), get_h = get(fen_h, idx);
int max_cnt = get_l + get_h;
int id_h_now = walkOnFen(fen_h, get_h);
int dist_h_now = sorted_val[id_h_now].fi;
if(get_h % 2 == 0)
return max_cnt;
// replace highest q with next lowest p
if(get_l < get(fen_l, 3 * numNode)) {
int id_l_now = 1 + walkOnFen(fen_l, get_l);
int dist_l_now = sorted_val[id_l_now].fi;
if(max_sum - dist_h_now + dist_l_now <= maxSum)
return max_cnt;
}
// replace highest p with highest q
if(get_l > 0) {
int id_l_now = 1 + walkOnFen(fen_l, get_l - 1);
int dist_l_now = sorted_val[id_l_now].fi;
if(max_sum - dist_l_now + dist_h_now <= maxSum)
return max_cnt;
}
return max_cnt - 1;
}
int calcWithCommon(void) {
sorted_diff.clear();
for (int i = 0; i < numNode; ++i)
sorted_diff.push_back({dist_h[i] - dist_l[i], dist_l[i], i});
sort(sorted_diff.begin(), sorted_diff.end(), [](const Data &a, const Data &b) {
return (a.dif != b.dif) ? a.dif < b.dif : a.val_l < b.val_l;
});
sorted_val.clear();
for (int i = 0; i < numNode; ++i) {
sorted_val.push_back(pli(2 * dist_l[i], i));
sorted_val.push_back(pli(dist_h[i], -2 * i - 2));
sorted_val.push_back(pli(dist_h[i], -2 * i - 1));
}
sort(sorted_val.begin(), sorted_val.end());
for (int i = 1; i <= 3 * numNode; ++i)
fen_dist[i] = fen_l[i] = fen_h[i] = 0;
ll sum_in_path(0);
int cnt_in_path(0), res(0);
for (int u = 0; u < numNode; ++u) {
if(inPath[u]) {
sum_in_path += dist_l[u];
++cnt_in_path;
continue;
}
int pos = upper_bound(sorted_val.begin(), sorted_val.end(), pli(2 * dist_l[u], u)) - sorted_val.begin();
modify(fen_dist, pos, 2 * dist_l[u]);
modify(fen_l, pos, +1);
}
if(sum_in_path <= maxSum) {
int cnt_optleft = getSumOptLeft(2 * (maxSum - sum_in_path));
res = cnt_in_path + cnt_optleft;
}
for (int i = 0; i < numNode; ++i) {
int u(sorted_diff[i].node);
if(inPath[u]) {
sum_in_path += dist_h[u] - dist_l[u];
++cnt_in_path;
} else {
int pos = upper_bound(sorted_val.begin(), sorted_val.end(), pli(2 * dist_l[u], u)) - sorted_val.begin();
modify(fen_dist, pos, -2 * dist_l[u]);
modify(fen_l, pos, -1);
pos = upper_bound(sorted_val.begin(), sorted_val.end(), pli(dist_h[u], -2 * u - 2)) - sorted_val.begin();
modify(fen_dist, pos, dist_h[u]);
modify(fen_h, pos, +1);
modify(fen_dist, pos + 1, dist_h[u]);
modify(fen_h, pos + 1, +1);
}
if(sum_in_path > maxSum)
break;
int cnt_optleft = getSumOptLeft(2 * (maxSum - sum_in_path));
res = max(res, cnt_in_path + cnt_optleft);
}
return res;
}
int calcWithoutCommon(void) {
vector<ll> sorted_dist;
for (int i = 0; i < numNode; ++i) {
sorted_dist.push_back(dist_l[i]);
sorted_dist.push_back(dist_h[i]);
}
sort(sorted_dist.begin(), sorted_dist.end());
ll tot_sum(0);
int res(0);
for (int i = 0; i < sz(sorted_dist); ++i) {
ll dis(sorted_dist[i]);
tot_sum += dis;
if(tot_sum <= maxSum)
res = i + 1;
}
return res;
}
int max_score(int _N, int _X, int _Y, ll _K, vector<int> _U, vector<int> _V, vector<int> _W) {
numNode = _N, x_node = _X, y_node = _Y, maxSum = _K;
for (int i = 0; i < numNode; ++i) {
adj[i].clear();
inPath[i] = 0;
}
for (int i = 0; i + 1 < numNode; ++i) {
int u(_U[i]), v(_V[i]), w(_W[i]);
adj[u].push_back(ii(v, w));
adj[v].push_back(ii(u, w));
}
dfs_init(x_node, -1, 0, dist_l, pa);
dfs_init(y_node, -1, 0, dist_h, pa);
for (int u = x_node; u != -1; u = pa[u])
inPath[u] = 1;
for (int i = 0; i < numNode; ++i) {
ll min_dist = min(dist_l[i], dist_h[i]);
ll max_dist = max(dist_l[i], dist_h[i]);
dist_l[i] = min_dist, dist_h[i] = max_dist;
}
return max(calcWithCommon(), calcWithoutCommon());
}
#ifdef Nhoksocqt1
int main(void) {
ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define TASK "closing"
if(fopen(TASK".inp", "r")) {
freopen(TASK".inp", "r", stdin);
freopen(TASK".out", "w", stdout);
}
vector<int> _U, _V, _W;
int _N, _X, _Y, _K;
cin >> _N >> _X >> _Y >> _K;
_U.resize(_N), _V.resize(_N), _W.resize(_N);
for (int i = 0; i + 1 < _N; ++i)
cin >> _U[i] >> _V[i] >> _W[i];
int x = max_score(_N, _X, _Y, _K, _U, _V, _W);
cout << "ANSWER: " << x << '\n';
return 0;
}
#endif // Nhoksocqt1
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
4952 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
249 ms |
58560 KB |
Output is correct |
2 |
Correct |
236 ms |
64316 KB |
Output is correct |
3 |
Correct |
126 ms |
10472 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
4956 KB |
Output is correct |
2 |
Incorrect |
2 ms |
4956 KB |
1st lines differ - on the 1st token, expected: '30', found: '31' |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
4956 KB |
Output is correct |
2 |
Incorrect |
2 ms |
4956 KB |
1st lines differ - on the 1st token, expected: '30', found: '31' |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
4956 KB |
Output is correct |
2 |
Incorrect |
2 ms |
4956 KB |
1st lines differ - on the 1st token, expected: '30', found: '31' |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
4952 KB |
Output is correct |
2 |
Correct |
2 ms |
4956 KB |
Output is correct |
3 |
Incorrect |
2 ms |
4956 KB |
1st lines differ - on the 1st token, expected: '30', found: '31' |
4 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
4952 KB |
Output is correct |
2 |
Correct |
2 ms |
4956 KB |
Output is correct |
3 |
Incorrect |
2 ms |
4956 KB |
1st lines differ - on the 1st token, expected: '30', found: '31' |
4 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
4952 KB |
Output is correct |
2 |
Correct |
2 ms |
4956 KB |
Output is correct |
3 |
Incorrect |
2 ms |
4956 KB |
1st lines differ - on the 1st token, expected: '30', found: '31' |
4 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
4952 KB |
Output is correct |
2 |
Correct |
2 ms |
4956 KB |
Output is correct |
3 |
Incorrect |
2 ms |
4956 KB |
1st lines differ - on the 1st token, expected: '30', found: '31' |
4 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
4952 KB |
Output is correct |
2 |
Correct |
2 ms |
4956 KB |
Output is correct |
3 |
Incorrect |
2 ms |
4956 KB |
1st lines differ - on the 1st token, expected: '30', found: '31' |
4 |
Halted |
0 ms |
0 KB |
- |