传送门:QAQQAQ

题意:原始有一棵根为1,有三个叶子2,3,4的树。有n个操作,每次可以在一个叶子下面续上两个节点,每次操作完问当前树的直径。

思路:先预处理出树的直径,以及其中一条直径两端的点l,r,对于新加的点,只需计算其与两端的距离(倍增LCA),若大于ans,则更新直径l或r,否则就不变

证明:假设加上点x后直径长为ans+1,因为x仅有一条边连它的父亲f,所以从f出发最远点距离为ans,即没加上点x前f为其中一条直径的端点。

因为各个直径两两相交(否则定可以在上方找到一条把两直径连起来,使直径更长),两直径前后两端不同区间一样长,所以从f出发到l,r定有一个距离为ans,所以这样的更新是没有反例的

补:树的直径dfs方法证明

1    设u为s-t路径上的一点,结论显然成立,否则设搜到的最远点为T(往下走)则

dis(u,T) >dis(u,s)     且  dis(u,T)>dis(u,t)   则最长路不是s-t了,与假设矛盾

2   设u不为s-t路径上的点

首先明确,假如u走到了s-t路径上的一点,那么接下来的路径肯定都在s-t上了,而且终点为s或t,在1中已经证明过了

所以现在又有两种情况了:

1:u走到了s-t路径上的某点,假设为X,最后肯定走到某个端点,假设是t ,则路径总长度为dis(u,X)+dis(X,t)

2:u走到最远点的路径u-T与s-t无交点,则dis(u,T) >dis(u,X)+dis(X,t);显然,如果这个式子成立,

则dis(s,X)+dis(X,u)+dis(u,T)>dis(s,X)+dis(X,t)=dis(s,t)  即dis(s,T)>dis(s,t) 最长路不是s-t矛盾    (摘自https://blog.csdn.net/frankax/article/details/79514778)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int inf=(int)(2e9);
 5 const ll INF=(ll)(5e18);
 6 const int N=1000010;//pay attention to the size of the array!!!
 7 const int M=30;
 8
 9 int n,l,r,num,ans;
10 int father[N][30],d[N];
11 vector<int> v[N];
12
13 void add_edge(int x,int y)
14 {
15     v[x].push_back(y);
16     father[y][0]=x;
17     for(int i=1;i<M;i++) father[y][i]=father[father[y][i-1]][i-1];
18     d[y]=d[x]+1;
19 }
20
21 void init()
22 {
23     num=5;
24     memset(father,0,sizeof(father));
25     for(int i=0;i<M;i++) father[1][i]=1;
26     d[1]=0; d[2]=d[3]=d[4]=1;
27 }
28
29 int LCA(int x,int y)
30 {
31     if(d[x]<d[y]) swap(x,y);
32     int dst=d[x]-d[y];
33     for(int i=M-1;i>=0;i--)
34     {
35         int tmp=(1<<i);
36         if(tmp<=dst)
37         {
38             dst-=tmp;
39             x=father[x][i];
40         }
41     }
42     for(int i=M-1;i>=0;i--)
43     {
44         if(father[x][i]==father[y][i]) continue;
45         x=father[x][i]; y=father[y][i];
46     }
47     return father[x][0];
48 }
49
50 int dis(int x,int y)
51 {
52     if(x==y) return 0;
53     int f=LCA(x,y);
54     return d[x]+d[y]-d[f]*2;
55 }
56
57 void solve(int x)
58 {
59     if(dis(x,l)>ans)
60     {
61         ans=dis(x,l);
62         r=x;//don't confuse the order of l&r
63     }
64     if(dis(x,r)>ans)
65     {
66         ans=dis(x,r);
67         l=x;
68     }
69 }
70
71 int main()
72 {
73     scanf("%d",&n);
74     init();
75     for(int i=2;i<=4;i++)
76     {
77         add_edge(1,i);
78     }
79     l=2,r=4,ans=2;
80     while(n--)
81     {
82         int x;
83         scanf("%d",&x);
84         add_edge(x,num);
85         add_edge(x,num+1);
86         solve(num);
87         num+=2;
88         printf("%d\n",ans);
89     }
90     return 0;
91 }

View Code

转载于:https://www.cnblogs.com/Forever-666/p/10660239.html

codeforces 379F-New Year Tree相关推荐

  1. Educational Codeforces Round 25 G. Tree Queries

    题目链接:Educational Codeforces Round 25 G. Tree Queries 题意: 给你一棵树,一开始所有的点全是黑色,有两种操作. 1 x 将x这个点变为黑色,保证第一 ...

  2. Codeforces 1129 E.Legendary Tree

    Codeforces 1129 E.Legendary Tree 解题思路: 这题好厉害,我来复读一下官方题解,顺便补充几句. 首先,可以通过询问 \(n-1​\) 次 \((S=\{1\},T=\{ ...

  3. Codeforces #1248B Grow The Tree题解(Java)

    Codeforces #1248B Grow The Tree题解(Java) 题目大意: 输入: 输出: 数据范围: 思路 代码 题目链接 题目大意: 给出一组线段(题目中叫树枝)的长度,制作成一条 ...

  4. Codeforces 463E Caisa and Tree

    Caisa and Tree 在dfs的过程中枚举质因子瞎搞搞就好啦, 不过这个题意真的表述不清.. #include<bits/stdc++.h> #define LL long lon ...

  5. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)

    题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...

  6. CodeForces - 620E New Year Tree(线段树+dfs序+状态压缩)

    题目链接:点击查看 题目大意:给出一棵无向树,每个节点都有一种颜色,接下来时m次操作: 1 x y:将x及其子树染成y的颜色 2 x:查询x及其子树上共有多少种不同的颜色 题目分析:看完这个题的第一反 ...

  7. Codeforces 699D Fix a Tree 并查集

    原题:http://codeforces.com/contest/699/problem/D 题目中所描述的从属关系,可以看作是一个一个块,可以用并查集来维护这个森林.这些从属关系中会有两种环,第一种 ...

  8. Codeforces 1278 D.Segment Tree(排序+set)

    题目链接:https://codeforces.com/contest/1278/problem/D 题目大意: 给定一堆线段[li,ri],每个线段的端点都不一样,如果两个线段相交,那么他们必须是有 ...

  9. CodeForces - 1287D Numbers on Tree(dfs+stl)

    题目链接:点击查看 题目大意:给出一棵有根树,每个节点都有一个权值,代表的是在其子树中有多少个节点的val比他小,现在要求根据每个点的权值构造出1~n的val数列 题目分析:因为数据量不大,n只有2e ...

  10. CodeForces - 618D Hamiltonian Spanning Tree(思维+贪心)

    题目链接:点击查看 题目大意:首先给出n个点,n*(n-1)/2条边组成的无向图,边的权值为y,现在给出一棵连接n个点的树,树上的权值都是x,现在问如何在每个点只遍历一次的情况下走遍n个点,并使一路上 ...

最新文章

  1. 为人父母始知天下事---“宝宝哭了”的问题来说说什么是分析,什么是设计
  2. 用linux集成电路版图设计,集成电路版图设计教程2012版本
  3. Intel Realsense D435 rs.rs2_deproject_pixel_to_point()函数(获取实际空间坐标)
  4. SpringCloud 02_什么是分布式、多线程、高并发?(浅析)
  5. Python办公自动化(一):从Word到Excel
  6. php mysql查询中文乱码_解决php mysql查询插入中文乱码问题_PHP教程
  7. Django项目实践2 - Django模板语言(常用语法规则)
  8. python爬虫知识点总结(十六)PySpider框架概述和用法详解
  9. 数据结构——一些小点
  10. 单机游戏mysql启动不了_魔域单机版MySQL数据库启动失败解决办法
  11. vc c语言标准库头文件,VC++ 6.0中添加库文件和头文件
  12. android实现3D地球转动组件,Rajawali3D基础教程-一个地球旋转的例子
  13. python入门ppt下载_Python3入门ppt
  14. [Python3] Python中单下划线和双下划线的含义
  15. Git 相关配置 用户名、邮箱
  16. 腾讯云标准型S3服务器独享100%CPU性能评测
  17. 软件工程项目——校园二手交易市场——数据流图
  18. github 私有化部署_用GitLab搭建自己的私有GitHub
  19. 凸轮轴曲轴位置传感器信号波形组合测试-汽车示波器
  20. 计算机知识竞赛的意义,IT活动丨“E”会玩计算机知识竞赛

热门文章

  1. 年度总结 | Flink 年度最佳学习路线总结
  2. 使用Anaconda进行环境和包的管理
  3. 原生开发安卓/iOS,Visual Studio迎神器扩展
  4. LSTM TF核心实现代码笔记
  5. mysql state_MySQL进程常见的State【转】
  6. 波兰表达式(前序表达式)的计算(栈)
  7. Gray Code(格雷码) C++多方法实现
  8. Java实战-坦克大战
  9. 看不懂简明python教程_简明python教程之Python文件头注释的含义,你肯定不懂
  10. linux 将程序链接到 usr bin,Linux / usr / bin文件在重新启动后消失