zoukankan      html  css  js  c++  java
  • CodeForces 379F 树的直径 New Year Tree

    题意:每次操作新加两个叶子节点,每次操作完以后询问树的直径。

    维护树的直径的两个端点U,V,每次计算一下新加进来的叶子节点到U,V两点的距离,如果有更长的就更新。

    因为根据树的直径的求法,若出现新的直径,一定是到U或者到V距离最远。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 const int maxn = 1000000 + 1000;
     7 const int logmaxn = 20;
     8 
     9 int n, Q;
    10 
    11 int L[maxn];
    12 int fa[maxn];
    13 int anc[maxn][logmaxn];
    14 
    15 void add(int u, int pa)
    16 {
    17     fa[u] = pa;
    18     L[u] = L[pa] + 1;
    19     anc[u][0] = pa;
    20     for(int j = 1; (1 << j) < n; j++) if(anc[u][j-1])
    21         anc[u][j] = anc[anc[u][j-1]][j-1];
    22 }
    23 
    24 int LCA(int p, int q)
    25 {
    26     if(L[p] < L[q]) std::swap(p, q);
    27     int log;
    28     for(log = 1; (1 << log) <= L[p]; log++); log--;
    29     for(int i = log; i >= 0; i--)
    30         if(L[p] - (1 << i) >= L[q]) p = anc[p][i];
    31     if(p == q) return p;
    32     for(int i = log; i >= 0; i--)
    33         if(anc[p][i] && anc[p][i] != anc[q][i])
    34             p = anc[p][i], q = anc[q][i];
    35     return fa[p];
    36 }
    37 
    38 int distance(int u, int v)
    39 {
    40     int l = LCA(u, v);
    41     return L[u] + L[v] - L[l] * 2;
    42 }
    43 
    44 int main()
    45 {
    46     scanf("%d", &Q);
    47     n = 4;
    48     fa[2] = fa[3] = fa[4] = 1;
    49     L[2] = L[3] = L[4] = 1;
    50     anc[2][0] = anc[3][0] = anc[4][0] = 1;
    51 
    52     int U = 2, V = 3, diameter = 2;
    53     while(Q--)
    54     {
    55         int p; scanf("%d", &p);
    56         add(++n, p);
    57         add(++n, p);
    58         int l1 = distance(n, U), l2 = distance(n, V);
    59         if(l1 >= l2 && l1 >= diameter)
    60         {
    61             V = n;
    62             diameter = l1;
    63         }
    64         else if(l2 >= l1 && l2 >= diameter)
    65         {
    66             U = n;
    67             diameter = l2;
    68         }
    69         printf("%d
    ", diameter);
    70     }
    71 
    72     return 0;
    73 }
    代码君
  • 相关阅读:
    Java设计模式(学习整理)---工厂模式
    Java Swing 使用总结(转载)
    Java-生成验证码图片(自定义内容,尺寸,路径)
    二维码(带有图片)的生成
    J2se中的声音---AudioPlayer
    文件的读取和写入(指定路径)
    ASP.NET:使用Flurl制作可复用的分页组件
    ASP.NET:Forms身份验证和基于Role的权限验证
    ASP.NET:MVC模板化机制
    ASP.NET:MVC中文件上传与地址变化处理
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4736285.html
Copyright © 2011-2022 走看看