zoukankan      html  css  js  c++  java
  • 森林 [树的直径]

    森林


    color{red}{正解部分}

    考虑在加节点时维护 直径 u,vu, v, 和距离 直径 最远的点 ss, 在询问时直接将 ss链 截到直径端点即可 .
    在加入一个节点 xx 时, 这个节点可能会替代 u,vu,v, 或者替代 ss,


    注意在计算 ss 离直径距离 时需要留心 ss 是否在 直径lca 下面, 计算方式不同 .


    color{red}{实现部分}

    #include<bits/stdc++.h>
    #define reg register
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 2e5 + 10;
    
    int N;
    int u;
    int v;
    int s;
    int Len;
    int dep[maxn];
    int Fk[maxn][20];
    
    int Lca(int x, int y){
            if(dep[x] < dep[y]) std::swap(x, y);
            for(reg int i = 19; i >= 0; i --) 
                    if(dep[Fk[x][i]] >= dep[y]) x = Fk[x][i];
            if(x == y) return x;
            for(reg int i = 19; i >= 0; i --)
                    if(Fk[x][i] != Fk[y][i]) x = Fk[x][i], y = Fk[y][i];
            return Fk[x][0];
    }
    
    int Dis(const int &x, const int &y){ return dep[x] + dep[y] - (dep[Lca(x, y)] << 1); }
    
    int Dis_2(int x){
            int lca = Lca(u, v);
            if(Lca(lca, x) == lca) return std::min(Dis(Lca(x, u), x), Dis(Lca(x, v), x));
            return Dis(lca, x);
    }
    
    void Add(int fa, int x){
            Fk[x][0] = fa; dep[x] = dep[fa] + 1;
            for(reg int i = 1; i <= 19; i ++) Fk[x][i] = Fk[Fk[x][i-1]][i-1];
            if(Dis(x, u) < Dis(x, v)) std::swap(u, v);
            int t = Dis(x, u);
            if(Len < t) Len = t, std::swap(x, v);
            if(Dis_2(x) > Dis_2(s)) s = x;
    }
    
    int main(){
            read(); N = read(); dep[1] = 1;
            u = v = s = 1;
            int last_ans = 0;
            for(reg int i = 2; i <= N; i ++){
                    int a = read() ^ last_ans;
                    Add(a, i);
                    printf("%d
    ", last_ans = Len + std::max(Dis_2(s)-1, 0));
            }
            return 0;
    }
    
  • 相关阅读:
    hlgoj 1766 Cubing
    Reverse Linked List
    String to Integer
    Bitwise AND of Numbers Range
    Best Time to Buy and Sell Stock III
    First Missing Positive
    Permutation Sequence
    Next Permutation
    Gray Code
    Number of Islands
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822463.html
Copyright © 2011-2022 走看看