【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}$表 ...
 
随机推荐
- C#数据流
			
C#编程中数据流的使用一直不很熟练,没有一个系统的认识,但是它的重要性显然不言而喻.System.IO下的Stream类是所有数据流的基类,当我们对数据进行逐字节操作时,首先需要将数据转换为数据流.C ...
 - 【LG4294】[WC2008]游览计划
			
[LG4294][WC2008]游览计划 题面 洛谷 bzoj 题解 斯坦纳树板子题. 斯坦纳树的总结先留个坑. 代码 #include <iostream> #include <c ...
 - 自己通过Cygwin编译的windowsx86下的更新至4.0.1
			
采用方法:https://my.oschina.net/maxid/blog/186506 方法中在3.2.6未找到src/redis.h文件 未修改 方法中 /deps/hiredis/net.c ...
 - Linux的常用命令笔记
			
这里使用的是centos操作系统 一.简单命令 (1)查看历史纪录: history (2)查看当前目录: pwd (3)查看系统当前时间和日期 date (4)查看当前登陆到系统的所有用户 who ...
 - appium自动化环境搭建
			
1.java开发环境JDK 2.android SDK(platform/platform tools/tools/build tools) 3.python下载安装(pip) 4.appium下载安 ...
 - idea compare功能 之一次bug修复
			
一次bug修复 最近开发完了一套单点系统,jenkins打包上传到服务器就出问题, 可以启动但是不能正常工作. 首先想到的是环境不一样, 于是把jenkins的jdk和maven都调整和本机大版本相同 ...
 - python购物车优化
			
一.需求分析 拥有用户接口和商家接口 用户能够进行消费记录查询,充值,购物等功能,消费记录存储于数据库 商家可以进行商品的增删改等操作 二.程序流程图 程序大致流程图如下: 三.代码实现 本程序分成两 ...
 - django项目中关于跨域CORS
			
1.使用django-cors-headers扩展,但首先进行安装 2.在配置中添加应用 3.在中间层中设置:“corsheaders.middleware.CorsMiddleware” 4.添加C ...
 - DOM---文档对象模型(Document Object Model)的基本使用
			
一.DOM简介 文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口.它是一种与平台和语言无关的应用程序接口(API),它可以动态 ...
 - PHP使用static关键字声明静态属性和静态方法
			
PHP使用static关键字声明静态属性和静态方法 在PHP中,通过static关键字修饰的成员属性和成员方法被称为静态属性和静态方法. 静态属性和静态方法不需要在被类实例化的情况下就可以直接使用. ...