【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林;询问一个点能到达的最远的点与该点的距离。强制在线。
$n\le 3\times 10^5$ ,$m\le 5\times 10^5$ 。
题解
树的直径+并查集+LCT
与直径相关的结论1:与一个点距离最大的点为任意一条直径的两个端点之一。
与直径相关的结论2:两棵树之间连一条边,新树直径的两个端点一定为第一棵树直径的两个端点和第二棵树直径的两个端点这四者中之二。
于是问题就变简单了,用并查集维护每个连通块的直径即可。由于强制在线,所以必须用LCT维护树上距离。
时间复杂度 $O(LCT·n\log n)=O(能过)$
#include <cstdio>
#include <algorithm>
#define N 300010
using namespace std;
int f[N] , px[N] , py[N] , fa[N] , c[2][N] , si[N] , rev[N];
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
inline void pushup(int x)
{
si[x] = si[c[0][x]] + si[c[1][x]] + 1;
}
inline void pushdown(int x)
{
if(rev[x])
{
swap(c[0][c[0][x]] , c[1][c[0][x]]) , rev[c[0][x]] ^= 1;
swap(c[0][c[1][x]] , c[1][c[1][x]]) , rev[c[1][x]] ^= 1;
rev[x] = 0;
}
}
inline bool isroot(int x)
{
return x != c[0][fa[x]] && x != c[1][fa[x]];
}
void update(int x)
{
if(!isroot(x)) update(fa[x]);
pushdown(x);
}
inline void rotate(int x)
{
int y = fa[x] , z = fa[y] , l = (c[1][y] == x) , r = l ^ 1;
if(!isroot(y)) c[c[1][z] == y][z] = x;
fa[x] = z , fa[y] = x , fa[c[r][x]] = y , c[l][y] = c[r][x] , c[r][x] = y;
pushup(y) , pushup(x);
}
inline void splay(int x)
{
int y , z;
update(x);
while(!isroot(x))
{
y = fa[x] , z = fa[y];
if(!isroot(y))
{
if((c[0][y] == x) ^ (c[0][z] == y)) rotate(x);
else rotate(y);
}
rotate(x);
}
}
inline void access(int x)
{
int t = 0;
while(x) splay(x) , c[1][x] = t , pushup(x) , t = x , x = fa[x];
}
inline void makeroot(int x)
{
access(x) , splay(x) , swap(c[0][x] , c[1][x]) , rev[x] ^= 1;
}
inline int dis(int x , int y)
{
makeroot(x) , access(y) , splay(y);
return si[y];
}
inline void link(int x , int y)
{
int tx = find(x) , ty = find(y) , mx = -1 , t , rx , ry;
makeroot(x) , fa[x] = y;
if(mx < (t = dis(px[tx] , py[tx]))) mx = t , rx = px[tx] , ry = py[tx];
if(mx < (t = dis(px[ty] , py[ty]))) mx = t , rx = px[ty] , ry = py[ty];
if(mx < (t = dis(px[tx] , px[ty]))) mx = t , rx = px[tx] , ry = px[ty];
if(mx < (t = dis(px[tx] , py[ty]))) mx = t , rx = px[tx] , ry = py[ty];
if(mx < (t = dis(py[tx] , px[ty]))) mx = t , rx = py[tx] , ry = px[ty];
if(mx < (t = dis(py[tx] , py[ty]))) mx = t , rx = py[tx] , ry = py[ty];
f[tx] = ty , px[ty] = rx , py[ty] = ry;
}
int main()
{
int type , n , q , i , opt , x , y , ans = 0;
scanf("%d%d%d" , &type , &n , &q);
for(i = 1 ; i <= n ; i ++ ) f[i] = px[i] = py[i] = i , si[i] = 1;
while(q -- )
{
scanf("%d%d" , &opt , &x) , x ^= ans;
if(opt == 1) scanf("%d" , &y) , y ^= ans , link(x , y);
else y = find(x) , printf("%d\n" , ans = max(dis(x , px[y]) , dis(x , py[y])) - 1);
if(!type) ans = 0;
}
return 0;
}
【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT的更多相关文章
- loj6038「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
题目传送门 https://loj.ac/problem/6038 题解 根据树的直径的两个性质: 距离树上一个点最远的点一定是任意一条直径的一个端点. 两个联通块的并的直径是各自的联通块的两条直径的 ...
- [loj6038]「雅礼集训 2017 Day5」远行 lct+并查集
给你 n 个点,支持 m 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. n≤3×10^5 n≤3×10^5 ,m≤5×10^5 m≤5 ...
- LOJ#6038. 「雅礼集训 2017 Day5」远行(LCT)
题面 传送门 题解 要不是因为数组版的\(LCT\)跑得实在太慢我至于去学指针版的么--而且指针版的完全看不懂啊-- 首先有两个结论 1.与一个点距离最大的点为任意一条直径的两个端点之一 2.两棵树之 ...
- 【刷题】LOJ 6038 「雅礼集训 2017 Day5」远行
题目描述 Miranda 生活的城市有 \(N\) 个小镇,一开始小镇间没有任何道路连接.随着经济发现,小镇之间陆续建起了一些双向的道路但是由于经济不太发达,在建设过程中,会保证对于任意两个小镇,最多 ...
- 「雅礼集训 2017 Day5」远行
题目链接 问题分析 要求树上最远距离,很显然就想到了树的直径.关于树的直径,有下面几个结论: 如果一棵树的直径两个端点为\(a,b\),那么树上一个点\(v\)开始的最长路径是\(v\rightarr ...
- loj#6038 「雅礼集训 2017 Day5」远行
分析 代码 #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define ...
- LOJ#6038. 「雅礼集训 2017 Day5」远行 [LCT维护子树的直径]
树的直径一定是原联通块4个里的组合 1.LCT,维护树的直径,这题就做完了 2.直接倍增,lca啥的求求距离,也可以吧- // powered by c++11 // by Isaunoya #inc ...
- 「雅礼集训 2017 Day5」珠宝
题目描述 Miranda 准备去市里最有名的珠宝展览会,展览会有可以购买珠宝,但可惜的是只能现金支付,Miranda 十分纠结究竟要带多少的现金,假如现金带多了,就会比较危险,假如带少了,看到想买的右 ...
- 「雅礼集训 2017 Day5」矩阵
填坑填坑.. 感谢wwt耐心讲解啊.. 如果要看这篇题解建议从上往下读不要跳哦.. 30pts 把$A$和$C$看成$n$个$n$维向量,那$A_i$是否加入到$C_j$中就可以用$B_{i,j}$表 ...
随机推荐
- 20155320 2016-2017-2《Java程序设计》第十二周课堂实践项目
20155320 2016-2017-2<Java程序设计>第十二周课堂实践项目 1.修改教材P98 Score2.java, 让执行结果数组填充是自己的学号: 2.在IDEA中以TDD的 ...
- 20155321 2016-2017-2 《Java程序设计》第九周学习总结
20155321 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 JDBC简介 厂商在实现JDBC驱动程序时,依方式可将驱动程序分为四种类型: JDBC-OD ...
- lamp环境搭建(centos6.9+apache2.4+mysql5.7+php7.1)
lamp环境搭建(centos6.9+apache2.4+mysql5.7+php7.1) 安装前准备:CentOS 6.9 64位 最小化安装 yum install -y make gcc gcc ...
- selenium自动化之元素定位方法
在使用selenium webdriver进行元素定位时,有8种基本元素定位方法(注意:并非只有8种,总共来说,有16种). 分别介绍如下: 1.name定位 (注意:必须确保name属性值在当前ht ...
- PS1修改xshell命令行样式
linux 其他知识目录 在/root/.bashrc下加入如下代码. export PS1='\n\e[1;37m[\e[m\e[1;32m\u\e[m\e[1;33m@\e[m\e[1;35m\H ...
- 清空git缓存
git rm -r --cached .git add . git commit -m 'update .gitignore' 读了下git文档,才发现,这些东西其实很简单,很容易理解.cached其 ...
- pip安装Crypto注意事项
pip install PyCrypto 1.使用pip install Crypto的方式安装的文件夹名称为crypto,而内部引用都用的Crypto路径,因此pip安装后,需要将文件夹名称修改为C ...
- LCA最近公共祖先(Tarjan离线算法)
这篇博客对Tarjan算法的原理和过程模拟的很详细. 转载大佬的博客https://www.cnblogs.com/JVxie/p/4854719.html 第二次更新,之前转载的博客虽然胜在详细,但 ...
- Beta发布——美工+文案
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2408项目地址:https://coding.net/u/wuyy694/ ...
- 福大软工1816:Beta(6/7)
Beta 冲刺 (6/7) 队名:第三视角 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务 文字/口头描述 组织会议 开发wxpy部分功能 展示G ...