可以证明,如果合并两棵树,新的直径的端点一定是原来两树中直径的端点

可以把新加两个点的操作看成是把两个只有一个点的树合并到原来的树上,然后用其中的一个点去和原来树上的直径两端点更新直径就可以了

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=5e5+10;
 7
 8 inline ll rd(){
 9     ll x=0;char c=getchar();int neg=1;
10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*neg;
13 }
14
15 int fa[maxn*2][22],dep[maxn*2];
16 int Q,ra,rb,r;
17
18 inline int getdis(int x,int y){
19     int re=dep[x]+dep[y];
20     if(dep[x]<dep[y]) swap(x,y);
21     for(int i=log2(dep[x]-dep[y]);i>=0&&dep[x]!=dep[y];i--){
22         if(fa[x][i]&&dep[fa[x][i]]>=dep[y])
23             x=fa[x][i];
24     }
25     int lca;
26     if(x==y) lca=x;
27     else{
28         for(int i=log2(dep[x]);i>=0;i--){
29             if(fa[x][i]!=fa[y][i])
30                 x=fa[x][i],y=fa[y][i];
31         }
32         lca=fa[x][0];
33     }
34     return re-dep[lca]*2;
35 }
36
37 int main(){
38     //freopen("","r",stdin);
39     int i,j,k;
40     Q=rd();
41     fa[2][0]=fa[3][0]=fa[4][0]=1;
42     dep[2]=dep[3]=dep[4]=2;dep[1]=1;
43     ra=2,rb=4;r=2;
44     for(i=1,j=4;i<=Q;i++){
45         int x=++j,y=++j;
46         fa[x][0]=fa[y][0]=rd();
47         dep[x]=dep[y]=dep[fa[x][0]]+1;
48         for(k=0;fa[x][k]&&fa[fa[x][k]][k];k++)
49             fa[x][k+1]=fa[y][k+1]=fa[fa[x][k]][k];
50         int r1=getdis(ra,x),r2=getdis(rb,x);
51         if(r1>r&&r1>=r2){
52             r=r1,rb=x;
53         }else if(r2>r){
54             r=r2,ra=x;
55         }
56         printf("%d\n",r);
57     }
58     return 0;
59 }

转载于:https://www.cnblogs.com/Ressed/p/9811228.html

cf379F New Year Tree (树的直径+倍增lca)相关推荐

  1. CodeForces-734E Anton and Tree 树的直径

    题目大意: 给定一棵有n个节点的树,有黑点白点两种节点. 每一次操作可以选择一个同种颜色的联通块将其染成同一种颜色 现在给定一个初始局面问最少多少步可以让树变为纯色. 题解: 首先我们拿到这棵树时先将 ...

  2. 【Codeforces613D】Kingdom and its Cities【虚树】【Tree DP】倍增lca

    http://codeforces.com/problemset/problem/613/D 题意: 给出n个点的树,有q个询问,每次询问给出k个重要的点,问至少删掉多少个非重要的点,使得这个重要的点 ...

  3. 【倍增算法】CF379F New Year Tree 题解

    In LuoGu 题目大意: 每次在给定节点增加两个点,动态输出当时树的直径,注意强制动态. 思路详解: 对于新加入的两个节点,新树的直径必定在两个点到另一个叶子节点的距离中,否则,新树的直径肯定和原 ...

  4. 牛客 - 王国(虚树+树的直径)

    题目链接:点击查看 题目大意:给出 n 个点组成的一棵树,每个节点都有一个权值,现在规定权值相同的节点之间,简单路径的边数为 x ,求 x * x 的最大值 题目分析:真的很巧,上周刚学的虚树,读完这 ...

  5. 2019长沙学院新生赛(A水,B水,C(整除分块),D水,E(巧数学),F(二分+bfs),H(换根dp),I(线段树)J(dp+倍增+lca))

    A-XOR SUM 通过简单观察得知连续四个数的异或值就是等于0,暴力找出左区间和右区间就可以了,最多跑四个单位 0^1^2^3==0   4^5^6^7=0 #include<bits/std ...

  6. 0x63.图论 - 树的直径与最近公共祖先

    目录 一.树的直径(Diameter) 1.树形DP求树的直径 2.两次BFS/DFS求树的直径 1.POJ 1985.Cow Marathon(DFS求树的直径模板题) 2.AcWing 350. ...

  7. 求树的直径的两种方法

    树的直径 树型dp求树的直径 优缺点: 优点为可以处理边权为负的情况,但不易得到直径的路径(指树的直径经过什么点). 代码模板: #include<bits/stdc++.h> using ...

  8. 树的直径,树的重心,树的分冶

    主要是利用了反证法: 假设 s-t这条路径为树的直径,或者称为树上的最长路 现有结论,从任意一点u出发搜到的最远的点一定是s.t中的一点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两 ...

  9. 《鲁滨逊漂流记》题解(LCA算法求树的直径)

    Description <鲁滨逊漂流记>只讲到了鲁滨逊在岛上建立起一个自给自足的生态环境.而大家不知道的是,在此之后,鲁滨逊因为太无聊,开始探索周边的岛屿,一共 NNN 天.鲁滨逊第 11 ...

最新文章

  1. 【Java常识】6.0面向对象认知和Eclipse的实用使用、==号和equals方法的区别
  2. windows下安装emscripten
  3. Zjoi2010排列计数Perm
  4. android拍照识别人脸,Android 人脸识别拍照demo
  5. matlab 不单调 插值,三组无关数据进行MATLAB画三维图不采用插值的方法该怎么办...
  6. Uboot中start.S源码的指令级的详尽解析(转)
  7. 用了Dapper之后通篇还是SqlConnection,真的看不下去了
  8. 【Python学习】 - 如何在Spyder中弹出plot绘图窗口而不是在Console中绘图
  9. CVPR 2019 | 步步为营!通过迭代式模糊核预测提高超分辨质量
  10. ckfinder java 源码,关于不再找java使用CKFinder的原因
  11. 51单片机IIC总线编程
  12. Spring(2)----IoC基础
  13. c语言答辩中期报告,安徽工程大学毕业设计(论文)中期检查总结
  14. 工信部召开地方信息安全工作会议
  15. AspNetPager 与分页存储过程详解
  16. 游戏加加导致cpu降频
  17. 三菱Q系列plc11轴运动控制程序
  18. [C++] 开灯问题(两个思路)
  19. JDO持久框架——DataNucles
  20. MySQL 8.0 新特性之哈希连接(Hash Join)

热门文章

  1. mysql 统计时长_使用 mysql 统计平均用户在线时长
  2. cin、cin.get()、cin.getline()、getline()总结
  3. Python爬虫(四)
  4. 创业板首批十家公司今天集体招股
  5. 外观设计专利侵权怎么认定
  6. Ubuntu22.04Desktop桌面版设置静态Ip
  7. css文字渐变色设置
  8. idea添加方法注释模板
  9. Golang 切片拼接
  10. Linux内核参数调优以应对SYN攻击