Submission #1370879

#TimeUsernameProblemLanguageResultExecution timeMemory
1370879SpyrosAlivMeetings 2 (JOI21_meetings2)C++20
100 / 100
190 ms50180 KiB
#include <bits/stdc++.h>
using namespace std;

const int MN = 2e5+5;
const int LOG = 20;

int up[MN][LOG], dep[MN], tin[MN], tout[MN], t = 0, sub[MN];

int n, currA = -1, currB = -1;
bool rem[MN];
int sz[MN], deg[MN];
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> leaves;
vector<vector<int>> tree;
vector<vector<int>> willAdd;

bool is_anc(int u, int v) {
    return tin[u] <= tin[v] && tout[u] >= tout[v];
}

int get_lca(int u, int v) {
    if (u == v) return u;
    if (dep[u] < dep[v]) swap(u, v);
    for (int i = LOG-1; i >= 0; i--) {
        if (!is_anc(up[u][i], v)) u = up[u][i];
    }
    return up[u][0];
}

int get_dist(int u, int v) {
    if (u == v) return 1;
    int lca = get_lca(u, v);
    return dep[u] + dep[v] - 2 * dep[lca] + 1;
}

void prec(int node, int prev = 0) {
    tin[node] = t++;
    up[node][0] = prev;
    for (int i = 1; i < LOG; i++) {
        up[node][i] = up[up[node][i-1]][i-1];
    }
    sub[node] = 1;
    for (auto next: tree[node]) {
        if (next == prev) continue;
        dep[next] = dep[node] + 1;
        prec(next, node);
        sub[node] += sub[next];
    }
    tout[node] = t++;
}

pair<int, int> max_dis(int node, int prev = 0) {
    if (rem[node]) return {-10, -10};
    pair<int, int> cand = {node, 1};
    for (auto next: tree[node]) {
        if (next == prev) continue;
        pair<int, int> might = max_dis(next, node);
        might.second++;
        if (might.second > cand.second) cand = might;
    }
    return cand;
}

void get_diam() {
    int st = -1;
    for (int i = 1; i <= n; i++) {
        if (!rem[i]) st = i;
    }
    assert(st != -1);
    currA = max_dis(st).first;
    currB = max_dis(currA).first;
}

void remove_nodes(int b) {
    while (!leaves.empty() && leaves.top().first < b) {
        int curr = leaves.top().second;
        rem[curr] = true;
        leaves.pop();
        for (auto next: tree[curr]) {
            if (rem[next]) continue;
            sz[next] += sz[curr];
            deg[next]--;
            if (deg[next] == 1) {
                leaves.push({sz[next], next});
            }
        }
        willAdd[2*b-1].push_back(curr);
    }
}

void solve() {
    cin >> n;
    tout[0] = 100*n;
    tree.resize(n+1);
    for (int i = 1; i < n; i++) {
        int u, v; cin >> u >> v;
        tree[u].push_back(v);
        tree[v].push_back(u);
    }
    prec(1, 0);
    for (int i = 1; i <= n; i++) {
        sz[i] = 1;
        deg[i] = tree[i].size();
    }
    for (int i = 1; i <= n; i++) {
        if (deg[i] == 1) leaves.push({sz[i], i});
    }
    willAdd.resize(n+1);
    for (int k = 2; k <= n; k += 2) {
        remove_nodes(k / 2);
    }
    get_diam();
    vector<int> ans;
    for (int k = n; k >= 1; k--) {
        for (auto x: willAdd[k]) {
            int currD = get_dist(currA, currB);
            int dA = get_dist(x, currA);
            int dB = get_dist(x, currB);
            if (currD >= dA && currD >= dB) continue;
            else if (dA >= currD && dA >= dB) {
                currB = x;
            }
            else if (dB >= currD && dB >= currD) {
                currA = x;
            }
        }
        if (k & 1) {
            ans.push_back(1);
        }
        else {
            ans.push_back(get_dist(currA, currB));
        }
    }
    reverse(ans.begin(), ans.end());
    for (auto x: ans) cout << x << "\n";
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    solve();
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...