QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#136049 | #6350. MIT | RedDiamond | WA | 2ms | 21892kb | C++14 | 5.4kb | 2023-08-06 20:04:52 | 2023-08-06 20:04:56 |
Judging History
answer
#include <bits/stdc++.h>/// to be continued
using namespace std;
typedef long long ll;
const int N = (int) 1e5 + 7;
const int K = 20;
const ll INF = (ll) 1e18;
int tin[N];
int tout[N];
int who[N];
int par[N];
int tab[K][N];
int depth[N];
ll dist[N];
ll sol[N];
vector<pair<int, ll>> g[N];
int n;
int tt = 0;
void dfs(int a, int p = 0) {
tin[a] = ++tt;
who[tt] = a;
par[a] = p;
for (auto &b : g[a]) {
if (b.first == p) {
continue;
}
depth[b.first] = dist[a] + 1;
dist[b.first] = dist[a] + b.second;
dfs(b.first, a);
}
tout[a] = tt;
}
int lca(int a, int b) {
if (depth[a] < depth[b]) {
swap(a, b);
}
for (int k = K - 1; k >= 0; k--) {
if (depth[b] + (1 << k) <= depth[a]) {
b = tab[k][b];
}
}
if (a == b) {
return a;
}
for (int k = K - 1; k >= 0; k--) {
if (tab[k][a] != tab[k][b]) {
a = tab[k][a];
b = tab[k][b];
}
}
return tab[0][a];
}
ll distance(int a, int b) {
return dist[a] + dist[b] - dist[lca(a, b)];
}
int aib[N];
void add(int i, int x) {
while (i < N) {
aib[i] += x;
i += i & (-i);
}
}
int get(int i) {
int sol = 0;
while (i) {
sol += aib[i];
i -= i & (-i);
}
return sol;
}
int kth(int k) {
int pos = 0;
int cnt = 0;
for (int kk = K - 1; kk >= 0; kk--) {
if (pos + (1 << kk) <= k && cnt + aib[pos + (1 << kk)] < k) {
cnt += aib[pos + (1 << kk)];
pos += (1 << kk);
}
}
pos++;
return who[pos];
}
int jump(int a, int sz) {
int aux = get(tout[a]) - get(tin[a] - 1);
if (aux >= sz) {
return a;
} else {
for (int k = K - 1; k >= 0; k--) {
int p = tab[k][a];
if (p != 0) {
int auxx = get(tout[p]) - get(tin[p] - 1);
if (auxx < sz) {
a = p;
}
}
}
return tab[0][a];
}
}
vector<int> centroid;
vector<int> getcentroid(int k) {
int mid = (k / 2 + 1);
int cen1 = jump(mid, (k + 1) / 2);
int sum1 = get(tout[cen1]) - get(tin[cen1] - 1);
if (k % 2 == 1) {
return {cen1};
}
int one = kth(1);
int cen2 = jump(one, (k + 1) / 2);
int sum2 = get(tout[cen2]) - get(tin[cen2] - 1);
if (sum2 == k / 2) {
return {cen1, cen2};
} else if (sum1 == k / 2) {
int cen3 = jump(mid, k / 2 + 1);
return {cen3, cen1};
} else if (depth[cen1] < depth[cen2]) {
return {cen2};
} else {
return {cen1};
}
}
ll segt[4 * N], lazy[4 * N], mn[4 * N];
ll cur = 0;
void build(int v, int tl, int tr) {
if (tl == tr) {
int x = who[tl];
ll aux = distance(centroid[0], x);
cur += aux;
if ((int) centroid.size() == 2) {
aux = max(aux, distance(centroid[1], x));
}
segt[v] = lazy[v] = aux;
mn[v] = tl;
return;
}
int tm = (tl + tr) / 2;
build(2 * v, tl, tm);
build(2 * v + 1, tm + 1, tr);
segt[v] = min(segt[2 * v], segt[2 * v + 1]);
if (segt[2 * v] <= segt[2 * v + 1]) {
mn[v] = mn[2 * v];
} else {
mn[v] = mn[2 * v + 1];
}
}
void push(int v, int tl, int tr) {
if (tl < tr) {
lazy[2 * v] += lazy[v];
lazy[2 * v + 1] += lazy[v];
}
segt[v] += lazy[v];
lazy[v] = 0;
}
void apply(int v, int tl, int tr, int x, int y, ll val) {
push(v, tl, tr);
if (x <= tl && tr <= y) {
lazy[v] += val;
push(v, tl, tr);
return;
}
int tm = (tl + tr) / 2;
if (x <= tm) {
apply(2 * v, tl, tm, x, min(tm, y), val);
}
if (tm + 1 <= y) {
apply(2 * v + 1, tm + 1, tr, max(x, tm + 1), y, val);
}
push(2 * v, tl, tm);
push(2 * v + 1, tm + 1, tr);
segt[v] = min(segt[2 * v], segt[2 * v + 1]);
if (segt[2 * v] <= segt[2 * v + 1]) {
mn[v] = mn[2 * v];
} else {
mn[v] = mn[2 * v + 1];
}
}
signed main() {
#ifdef ONPC
freopen ("input.txt", "r", stdin);
#else
ios::sync_with_stdio(0); cin.tie(0);
#endif // ONPC
cin >> n;
for (int i = 1; i < n; i++) {
int x, y, z;
cin >> x >> y >> z;
g[x].push_back({y, z});
g[y].push_back({x, z});
}
{
dfs(1);
for (int i = 1; i <= n; i++) {
tab[0][i] = par[i];
}
for (int k = 1; k < K; k++) {
for (int i = 1; i <= n; i++) {
tab[k][i] = tab[k - 1][tab[k - 1][i]];
}
}
}
for (int i = 1; i <= n; i++) {
add(i, 1);
}
centroid = getcentroid(n);
build(1, 1, n);
sol[n] = cur;
for (int i = n - 1; i >= 2; i--) {
int x = who[mn[1]];
sol[i] = sol[i + 1] - mn[1];
apply(1, 1, n, tin[x], tin[x], INF);
add(tin[x], -1);
vector<int> c = getcentroid(i);
if ((int) c.size() == 2) {
int cc1 = c[0], cc2 = c[1];
if (depth[cc1] < depth[cc2]) {
swap(cc1, cc2);
}
ll d1 = distance(cc2, centroid[0]);
ll d2 = distance(cc1, centroid[0]);
apply(1, 1, n, tin[cc1], tout[cc1], d1 - d2);
apply(1, 1, n, 1, n, d2);
} else if ((int) centroid.size() == 2) {
int cc1 = centroid[0], cc2 = centroid[1];
if (depth[cc1] < depth[cc2]) {
swap(cc1, cc2);
}
ll d = distance(cc1, cc2);
if (cc2 == c[0]) {
apply(1, 1, n, tin[cc1], tout[cc1], d);
apply(1, 1, n, 1, n, -d);
} else {
apply(1, 1, n, tin[cc1], tout[cc1], -d);
}
}
centroid = c;
}
for (int i = 2; i <= n; i += 2) {
cout << sol [i] << " ";
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 2ms
memory: 21892kb
input:
7 1 3 99 2 3 82 3 4 4 4 5 43 5 6 5 4 7 3
output:
1285 1293 1304
result:
wrong answer 1st numbers differ - expected: '181', found: '1285'