zoukankan      html  css  js  c++  java
  • [Usaco2018 Feb] New Barns

    [题目链接]

            https://www.lydsy.com/JudgeOnline/problem.php?id=5192

    [算法]

            维护树的直径,在树上离一个点最远的点一定是一条直径的端点。

            在直径为(x , y)的树上加入一个叶子结点z,则新的直径必然为(x , y) , (x , z) , (y , z)中的一条 , 问题转化为询问树上两点距离 , 倍增即可 , 时间复杂度 :O(MlogN)

    [代码]

             

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 1e5 + 10;
    const int MAXLOG = 20;
    
    int n , total , k;
    int depth[MAXN] , x[MAXN] , y[MAXN] , belong[MAXN];
    int anc[MAXN][MAXLOG];
    char op[5];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline int lca(int u,int v)
    {
            if (depth[u] > depth[v]) swap(u , v);
            for (int i = MAXLOG - 1; i >= 0; i--)
            {
                    if (depth[anc[v][i]] >= depth[u])
                            v = anc[v][i];
            }
            if (u == v) return u;
            for (int i = MAXLOG - 1; i >= 0; i--)
            {
                    if (anc[u][i] != anc[v][i])
                            u = anc[u][i] , v = anc[v][i];
            }
            return anc[u][0];
    }
    inline int dist(int x,int y)
    {
            return depth[x] + depth[y] - 2 * depth[lca(x , y)];
    }
    inline void update(int u)
    {
            int tmp = belong[u];
            int nx , ny , nd;
            if (dist(u , x[tmp]) > dist(u , y[tmp]))
            {
                    nd = dist(u , x[tmp]);
                    nx = u; 
                    ny = x[tmp];
            }    else
            {
                    nd = dist(u , y[tmp]);
                    nx = u;
                    ny = y[tmp];
            }
            if (nd > dist(x[tmp] , y[tmp]))
            {
                    x[tmp] = nx;
                    y[tmp] = ny;
            }
    }
    inline int query(int k)
    {
            int tmp = belong[k];
            return max(dist(k , x[tmp]) , dist(k , y[tmp])); 
    }
     
    int main()
    {
            
            int Q;
            scanf("%d",&Q);
            while (Q--)
            {
                    scanf("%s%d",&op , &k);
                    if (op[0] == 'B')
                    {
                            ++n;
                            if (k == -1)
                            {
                                    belong[n] = ++total;
                                    anc[n][0] = 0;
                                    depth[n] = 1;    
                                    x[total] = y[total] = n;
                            } else
                            {
                                    depth[n] = depth[k] + 1;
                                    anc[n][0] = k;
                                    for (int i = 1; i < MAXLOG; i++)
                                            anc[n][i] = anc[anc[n][i - 1]][i - 1];
                                    belong[n] = belong[k];
                            }
                            update(n);
                    } else printf("%d
    ",query(k));
            }
            
            return 0;
        
    }
  • 相关阅读:
    LeetCode Find Duplicate File in System
    LeetCode 681. Next Closest Time
    LeetCode 678. Valid Parenthesis String
    LeetCode 616. Add Bold Tag in String
    LeetCode 639. Decode Ways II
    LeetCode 536. Construct Binary Tree from String
    LeetCode 539. Minimum Time Difference
    LeetCode 635. Design Log Storage System
    LeetCode Split Concatenated Strings
    LeetCode 696. Count Binary Substrings
  • 原文地址:https://www.cnblogs.com/evenbao/p/9827327.html
Copyright © 2011-2022 走看看