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;
        
    }
  • 相关阅读:
    php之curl实现http与https请求的方法
    Linux学习之CentOS(十)--虚拟机下的CentOS如何上网
    php--yii2框架错误提示
    Vmware安装与VMware下Linux系统安装
    Git命令
    PHP--yii中findOne转换成数组
    Window上装PHP开发环境 (XAMPP)
    yii2.0框架中session与cookie的用法
    【网站架构】从简单到复杂,一步步演变
    nginx 配置反向代理,负载均衡实战解析
  • 原文地址:https://www.cnblogs.com/evenbao/p/9827327.html
Copyright © 2011-2022 走看看