Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const int inf = 1e9 + 5, nmax = 1e5 + 5, nbit = 18;
- int n;
- vector< int > g[nmax];
- namespace CentroidDecompLmfao {
- namespace AINT {
- int aint[nmax * 4];
- void erase(int poz, int node = 1, int cl = 1, int cr = n) {
- if(cl == cr) {
- aint[node] = inf;
- return;
- }
- int mid = cl + cr >> 1;
- if(poz <= mid)
- erase(poz, 2 * node, cl, mid);
- else
- erase(poz, 2 * node + 1, mid + 1, cr);
- aint[node] = min(aint[2 * node], aint[2 * node + 1]);
- }
- int _query(int l, int r, int node = 1, int cl = 1, int cr = n) {
- if(l <= cl && cr <= r)
- return aint[node];
- if(r < cl || cr < l)
- return inf;
- int mid = cl + cr >> 1;
- return min(_query(l, r, 2 * node, cl, mid), _query(l, r, 2 * node + 1, mid + 1, cr));
- }
- int construct(int *p, int node = 1, int cl = 1, int cr = n) {
- if(cl == cr)
- return aint[node] = p[cl];
- int mid = cl + cr >> 1;
- return aint[node] = min(construct(p, 2 * node, cl, mid), construct(p, 2 * node + 1, mid + 1, cr));
- }
- int query(int l, int r, int node = 1, int cl = 1, int cr = n) {
- if(r < l)
- return inf;
- return _query(l, r);
- }
- }
- namespace LCA {
- int p[nbit][nmax];
- int pin[nmax], pout[nmax], inp = 1, preord[nmax], depth[nmax];
- void init(int node, int f) {
- p[0][node] = f;
- for(int i = 1; i < nbit; i++)
- p[i][node] = p[i - 1][p[i - 1][node]];
- pin[node] = inp;
- preord[inp++] = node;
- depth[node] = depth[f] + 1;
- for(auto x : g[node])
- if(x != f)
- init(x, node);
- pout[node] = inp - 1;
- return;
- }
- bool isanc(int f, int node) { return pin[f] <= pin[node] && pout[node] <= pout[f]; }
- int lca(int x, int y) {
- if(isanc(x, y))
- return x;
- if(isanc(y, x))
- return y;
- for(int i = nbit - 1; i >= 0; i--) {
- if(!isanc(p[i][x], y))
- x = p[i][x];
- }
- return p[0][x];
- }
- }
- #warning clist sa aiba santinela
- vector< vector<int> > clist;
- int atrcol[nmax];
- void insert( int x, int col) {
- clist[col].push_back(x);
- atrcol[x] = col;
- AINT::erase(LCA::pin[x]);
- }
- void descend(int node);
- void solve(int l, int r);
- int descend(int L, int R, int node, int col) {
- vector<pair<int,int> > candid;
- insert(node, col);
- for(auto x : g[node]) {
- if(atrcol[x] != 0)
- continue;
- if(x == LCA::p[0][node]) {
- candid.push_back({min(AINT::query(L, LCA::pin[node] - 1), AINT::query(LCA::pout[node] + 1, R)), x});
- continue;
- }
- candid.push_back({AINT::query(LCA::pin[x], LCA::pout[x]), x});
- }
- sort(candid.begin(), candid.end());
- if(candid.size() == 0)
- return node;
- return descend(L, R, candid[0].second, col);
- }
- void solve(int l, int r) {
- if(r < l)
- return;
- pair<int,int> rez;
- int x, y, lca;
- x = AINT::query(l, r);
- if(x == inf) {
- return;
- }
- int currcol = clist.size();
- clist.push_back(vector<int>());
- insert(x, currcol);
- y = AINT::query(l, r);
- if(y == inf)
- return;
- rez = {x, y};
- insert(y, currcol);
- lca = LCA::lca(x, y);
- atrcol[lca] = currcol;
- while(x != lca) insert(x, currcol), x = LCA::p[0][x];
- while(y != lca) insert(y, currcol), y = LCA::p[0][y];
- insert(lca, currcol);
- tie(x, y) = rez;
- auto elim = [&](int node) {
- for(auto candidate : g[node])
- if(LCA::p[0][node] != candidate && atrcol[candidate] == 0)
- solve(LCA::pin[candidate], LCA::pout[candidate]);
- };
- tie(x, y) = rez;
- x = descend(l, r, x, currcol);
- y = descend(l, r, y, currcol);
- lca = LCA::lca(x, y);
- while(LCA::depth[x] > LCA::depth[lca]) elim(x), x = LCA::p[0][x];
- while(LCA::depth[y] > LCA::depth[lca]) elim(y), y = LCA::p[0][y];
- elim(lca);
- solve(l, r);
- }
- }
- using namespace CentroidDecompLmfao;
- map<int, int> modcol;
- int res[nmax];
- int main() {
- cin >> n;
- for(int i = 1, x, y; i < n; i++) {
- cin >> x >> y;
- g[x].push_back(y);
- g[y].push_back(x);
- }
- if(n == 1) {
- cout << "1\n";
- return 0;
- }
- clist.push_back(vector<int>());
- LCA::init(1, 1);
- AINT::construct(LCA::preord);
- solve(1, n);
- for(int i = 1, mn; i < clist.size(); i++) {
- mn = n;
- for(auto x : clist[i])
- mn = min(mn, x);
- modcol[mn] = i;
- }
- int count = 1;
- for(auto [mn, line] : modcol) {
- for(auto x : clist[line])
- res[x] = count;
- count++;
- }
- for(int i = 1; i <= n; i++)
- cout << res[i] << ' ';
- cout << '\n';
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement