【Foreign】远行 [LCT]
远行
Time Limit: 20 Sec Memory Limit: 256 MB
Description

Input

Output

Sample Input
0
5 10
1 4 5
2 3
2 5
2 1
1 5 3
1 1 4
2 3
2 5
1 5 2
2 1
Sample Output
0
1
0
3
2
3
HINT

Main idea
每次连上一条边,询问一个点和其能到达最远的点的距离。
Solution
由于每次要脸上一条边,我们显然使用LCT,然后一个点到达的最远的点必然是树的直径上的端点,我们合并两棵树维护直径的时候,暴力分几种情况讨论一下即可。
Code
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
using namespace std;
typedef long long s64; const int ONE = ;
const int MOD = 1e9+; int Type,n,Q;
int opt,x,y;
int fat[ONE];
int Ans; int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int Find(int x)
{
if(fat[x]==x) return x;
return fat[x]=Find(fat[x]);
} namespace LCT
{
int lc[ONE],rc[ONE],fa[ONE];
int hasRev[ONE];
int L[ONE],R[ONE],dis[ONE],size[ONE]; void pre()
{
for(int i=;i<=n;i++)
fat[i]=L[i]=R[i]=i,
size[i]=;
} void Update(int x)
{
size[x] = size[lc[x]] + size[rc[x]] + ;
} bool is_real(int x)
{
return (lc[fa[x]]==x || rc[fa[x]]==x);
} void tag_rev(int x)
{
hasRev[x]^=;
swap(lc[x],rc[x]);
} void tag_down(int x)
{
if(hasRev[x])
{
tag_rev(lc[x]);
tag_rev(rc[x]);
hasRev[x]=;
}
} void Turn(int x)
{
int y=fa[x],z=fa[y];
int b= x==lc[y]?rc[x]:lc[x]; fa[y]=x; fa[x]=z;
if(b) fa[b]=y; if(z)
{
if(y==lc[z]) lc[z]=x;
else if(y==rc[z]) rc[z]=x;
} if(x==lc[y]) rc[x]=y,lc[y]=b;
else lc[x]=y,rc[y]=b; Update(y); Update(x);
} void Splay(int x)
{
static int anc[ONE];
int anc_num=;
anc[++anc_num] = x;
for(int i=x; is_real(i); i=fa[i]) anc[++anc_num]=fa[i];
while(anc_num>) tag_down(anc[anc_num--]);
while(is_real(x))
{
if(is_real(fa[x]))
{
if( (lc[fa[x]]==x) == (lc[fa[fa[x]]]==fa[x]) ) Turn(fa[x]);
else Turn(x);
}
Turn(x);
}
} void access(int x)
{
for(int p=x,q=; p; q=p,p=fa[q])
{
Splay(p);
rc[p] = q;
Update(p);
}
} void make_root(int x)
{
access(x); Splay(x); tag_rev(x);
} int dist(int x,int y)
{
make_root(x); access(y); Splay(y); return size[y]-;
} void link(int x,int y)
{
int lx,rx,ly,ry;
int Fx=Find(x), Fy=Find(y);
fat[Fy] = Fx;
make_root(x); fa[x]=y;
lx = L[Fx]; rx = R[Fx]; ly = L[Fy]; ry = R[Fy]; if(dist(lx,rx) >= dis[Fx]) dis[Fx]=dist(lx,rx), L[Fx]=lx, R[Fx]=rx;
if(dist(ly,ry) >= dis[Fx]) dis[Fx]=dist(ly,ry), L[Fx]=ly, R[Fx]=ry; if(dist(lx,ly) >= dis[Fx]) dis[Fx]=dist(lx,ly), L[Fx]=lx, R[Fx]=ly;
if(dist(lx,ry) >= dis[Fx]) dis[Fx]=dist(lx,ry), L[Fx]=lx, R[Fx]=ry;
if(dist(rx,ly) >= dis[Fx]) dis[Fx]=dist(rx,ly), L[Fx]=rx, R[Fx]=ly;
if(dist(rx,ry) >= dis[Fx]) dis[Fx]=dist(rx,ry), L[Fx]=rx, R[Fx]=ry; } void Query(int x)
{
int Fx=Find(x);
Ans = max( dist(L[Fx],x),dist(R[Fx],x) );
printf("%d\n",Ans);
}
} int main()
{
Type=get();
n=get(); Q=get();
LCT::pre();
while(Q--)
{
opt = get();
if(opt == )
{
x=get(); y=get();
if(Type==) x^=Ans, y^=Ans;
LCT::link(x,y);
}
else
{
x=get();
if(Type==) x^=Ans;
LCT::Query(x);
}
} }
【Foreign】远行 [LCT]的更多相关文章
- [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维护子树的直径]
树的直径一定是原联通块4个里的组合 1.LCT,维护树的直径,这题就做完了 2.直接倍增,lca啥的求求距离,也可以吧- // powered by c++11 // by Isaunoya #inc ...
- 4.17 省选模拟赛 远行 LCT 启发式合并 倍增
容易写出nQ的暴力 由于数据是期望的时间 所以直接dfs可以跑的很快 可以拿到70分. 当然 可以进一步优化暴力 使用换根dp 然后可以将暴力优化到n^2. const int MAXN=300010 ...
- 2019.2.28&2019.3.1 考试
因为没A/改几道题,就一起写了 题目在LOJ上都能找到 2019.2.28 100+20+12 前两个小时一直在睡觉+想题也没思路,我太菜了 T1 洗衣服 分开处理出洗衣服和烘干的时间,然后一边正着排 ...
- 【题解】【雅礼集训 2017 Day5】远行 LOJ 6038 LCT
Prelude 快要THUWC了,练一练板子. 传送到LOJ:o(TヘTo) Solution 首先有一条定理. 到树中任意一点的最远点一定是直径的两个端点之一. 我也不会证反正大家都在用,似乎可以用 ...
- LOJ#6038. 「雅礼集训 2017 Day5」远行(LCT)
题面 传送门 题解 要不是因为数组版的\(LCT\)跑得实在太慢我至于去学指针版的么--而且指针版的完全看不懂啊-- 首先有两个结论 1.与一个点距离最大的点为任意一条直径的两个端点之一 2.两棵树之 ...
- 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...
- 【Foreign】染色 [LCT][线段树]
染色 Time Limit: 20 Sec Memory Limit: 256 MB Description Input Output Sample Input 13 0 1 0 2 1 11 1 ...
- loj6038「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
题目传送门 https://loj.ac/problem/6038 题解 根据树的直径的两个性质: 距离树上一个点最远的点一定是任意一条直径的一个端点. 两个联通块的并的直径是各自的联通块的两条直径的 ...
随机推荐
- 封装一个ExcelHelper,方便将Excel直接转成Datatable对象
public class ExcelHelper { /// <summary> /// Excel转换成DataTable /// </summary> /// <pa ...
- babel配置
首页 首页 首页 博客园 博客园 博客园 联系我 联系我 联系我 demo demo demo GitHub GitHub GitHub 管理 管理 管理 魔魔魔芋芋芋铃铃铃 [02]websto ...
- Scala学习笔记(三):基础知识
有了可运行的环境,就需要写一些简单的语句来认识一下Scala,本文没有写那么详细,只是为了方便查看.唤起回忆 (1)变量的定义方法 Scala有两种变量 var val 注意:在解释器中,可以用一个之 ...
- Qt 实时读串口数据,并将读到的数据从网口发送出去
需求: 1. 要试试从串口读取数据 2. 将读到的数据从网口发送出去 3.开机启动 4. 没有界面 第一部分 配置Qt Pro文件 需要Qt += serialport network 第二部分 - ...
- Leetcode 675.为高尔夫比赛砍树
为高尔夫比赛砍树 你被请来给一个要举办高尔夫比赛的树林砍树. 树林由一个非负的二维数组表示, 在这个数组中: 0 表示障碍,无法触碰到. 1 表示可以行走的地面. 比1大的数 表示一颗允许走过的树的高 ...
- Spring定时器调用Hibernate方法无法获得SessionFactory的解决办法
由于在Spring定时器中无法通过注解的方式获取bean,因此需要通过原生的方式获取.获取session的方式如下: WebApplicationContext wac = ContextLoader ...
- mysql 查询表的字段数目
select column_name from information_schema.`COLUMNS` where TABLE_NAME ='tcm_head'
- 软工实践 - 第二十五次作业 Beta 冲刺(3/7)
队名:起床一起肝活队 组长博客:https://www.cnblogs.com/dawnduck/p/10116979.html 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过 ...
- Asp.Net生命周期系列一
Asp.Net生命周期对于初级甚至中级程序员来说,一直都是一个难题,很多程序员不了解生命周期,导致使用Asp.Net做开发感觉很不灵活,感觉太多东西被微软封装好了,我们不能改变,其实只要你稍微了解一下 ...
- StrutsResultSupport的使用
在有特殊情况时:如果没有异常信息,但是有错误并且有错误信息等内容:此时也需要进行友好的错误处理的话,那么可以借助StrutsResultSupport 返回结果类型来实现特定处理.此种方式先需要继承S ...