题目描述

Miranda 生活的城市有 \(N\) 个小镇,一开始小镇间没有任何道路连接。随着经济发现,小镇之间陆续建起了一些双向的道路但是由于经济不太发达,在建设过程中,会保证对于任意两个小镇,最多有一条路径能互相到达。有的时候 Miranda 会从某个小镇开始进行徒步旅行,每次出发前,她都想选择一个她能到达的最远的小镇作为终点,并且她在行走过程中是不会走回头路的,为了估算这次旅行的时间,她会需要你告诉她这次旅行的时间会是多少呢?可以假设通过每条道路都需要单位时间,并且 Miranda 不会在小镇停留。

输入格式

第一行一个整数 \(\text{type}\),表示数据类型。

第二行两个整数 \(N\)、\(Q\) 。

接下来 \(Q\) 行,每行先读入一个整数 \(t\) ,若 \(t = 1\) ,则接下来读入两个整数 \(u\) 、\(v\) ,表示小镇 \(u\) 与小镇 \(v\) 建立了一条新道路。若 \(t = 2\) ,读入一个整数 \(u\) ,表示 Miranda 要开始一次从小镇 \(u\) 出发的旅行。

  • 若 \(\text{type} = 1\) ,记 \(\text{lastAns}\) 表示最近一次 Miranda 旅行的时间,那么对于每次操作的 \(u\) 或 \(u, v\) ,都要异或上 \(\text{lastAns}\) 。

  • 若 \(\text{type} = 0\) ,则不需要对数据进行处理。

输出格式

对于每次询问,输出 Miranda 能到达的最远的小镇的距离是多少。注意 Miranda 可能只能留在开始的小镇。

样例

样例输入

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

样例输出

0
1
0
3
2
3

数据范围与提示

对于 \(20\%\) 的数据,\(N \leq 5000, Q \leq 10000\) ;

对于 \(50\%\) 的数据,\(N \leq 100000, Q \leq 200000\) ;

对于另外 \(20\%\) 的数据,\(\text{type} = 0\) ;

对于 \(100\%\) 的数据,\(N \leq 300000, Q \leq 500000, \text{type} \in \{ 0, 1 \}\) ,解密后的 \(u\) 、\(v\) 满足 \(1 \leq u, v \leq N\) ,且道路的修建会满足:每一时刻,都不存在 \(u, v\) 使得 \(u, v\) 之间能通过多种方式到达。

题解

直径的性质:

  1. 与一个点距离最大的点为任意一条直径的两个端点之一

  2. 两棵树之间连一条边,新树直径的两个端点一定为第一棵树直径的两个端点和第二棵树直径的两个端点这四者中之二

所以用LCT维护联通块直径的两个端点

查询时,把查询的点与两个端点分别split再询问size大小,取max即为答案

修改时,取出两个合并的联通块的直径的端点,四个,讨论6种情况,取距离最大的两个点为新的直径的端点

就这样就做完了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=300000+10;
int n,q,res,p1,p2,fa[MAXN],type,lastans;
std::pair<int,int> d[MAXN];
#define lc(x) ch[(x)][0]
#define rc(x) ch[(x)][1]
struct LinkCut_Tree{
int size[MAXN],ch[MAXN][2],fa[MAXN],rev[MAXN],stack[MAXN],cnt;
inline bool nroot(int x)
{
return lc(fa[x])==x||rc(fa[x])==x;
}
inline void reverse(int x)
{
std::swap(lc(x),rc(x));
rev[x]^=1;
}
inline void pushup(int x)
{
size[x]=size[lc(x)]+size[rc(x)]+1;
}
inline void pushdown(int x)
{
if(rev[x])
{
if(lc(x))reverse(lc(x));
if(rc(x))reverse(rc(x));
rev[x]=0;
}
}
inline void rotate(int x)
{
int f=fa[x],p=fa[f],c=(rc(f)==x);
if(nroot(f))ch[p][rc(p)==f]=x;
fa[ch[f][c]=ch[x][c^1]]=f;
fa[ch[x][c^1]=f]=x;
fa[x]=p;
pushup(f);
pushup(x);
}
inline void splay(int x)
{
cnt=0;
stack[++cnt]=x;
for(register int i=x;nroot(i);i=fa[i])stack[++cnt]=fa[i];
while(cnt)pushdown(stack[cnt--]);
for(register int y=fa[x];nroot(x);rotate(x),y=fa[x])
if(nroot(y))rotate((lc(fa[y])==y)==(lc(y)==x)?y:x);
pushup(x);
}
inline void access(int x)
{
for(register int y=0;x;x=fa[y=x])splay(x),rc(x)=y,pushup(x);
}
inline void makeroot(int x)
{
access(x);splay(x);reverse(x);
}
inline void split(int x,int y)
{
makeroot(x);access(y);splay(y);
}
inline void link(int x,int y)
{
makeroot(x);fa[x]=y;pushup(y);
}
};
LinkCut_Tree T;
#undef lc
#undef rc
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline int found(int x)
{
if(fa[x]!=x)fa[x]=found(fa[x]);
return fa[x];
}
inline void length(int x,int y)
{
T.split(x,y);
if(T.size[y]>res)res=T.size[y],p1=x,p2=y;
}
#define ft first
#define sd second
inline void modify(int x,int y)
{
std::pair<int,int> a=d[found(x)],b=d[found(y)];
res=0;T.link(x,y);
length(a.ft,a.sd);length(a.ft,b.ft);length(a.ft,b.sd);
length(a.sd,b.ft);length(a.sd,b.sd);length(b.ft,b.sd);
d[found(y)]=std::make_pair(p1,p2);
fa[found(x)]=found(y);
}
#undef ft
#undef sd
int main()
{
read(type);
read(n);read(q);
for(register int i=1;i<=n;++i)fa[i]=i,d[i]=std::make_pair(i,i);
while(q--)
{
int opt;read(opt);
if(opt==1)
{
int u,v;read(u);read(v);
if(type)u^=lastans,v^=lastans;
modify(u,v);
}
if(opt==2)
{
int u,ans=0;read(u);
if(type)u^=lastans;
std::pair<int,int> now=d[found(u)];
T.split(now.first,u);chkmax(ans,T.size[u]);
T.split(now.second,u);chkmax(ans,T.size[u]);
write(lastans=ans-1,'\n');
}
}
return 0;
}

【刷题】LOJ 6038 「雅礼集训 2017 Day5」远行的更多相关文章

  1. LOJ#6038. 「雅礼集训 2017 Day5」远行(LCT)

    题面 传送门 题解 要不是因为数组版的\(LCT\)跑得实在太慢我至于去学指针版的么--而且指针版的完全看不懂啊-- 首先有两个结论 1.与一个点距离最大的点为任意一条直径的两个端点之一 2.两棵树之 ...

  2. LOJ#6038. 「雅礼集训 2017 Day5」远行 [LCT维护子树的直径]

    树的直径一定是原联通块4个里的组合 1.LCT,维护树的直径,这题就做完了 2.直接倍增,lca啥的求求距离,也可以吧- // powered by c++11 // by Isaunoya #inc ...

  3. loj#6038 「雅礼集训 2017 Day5」远行

    分析 代码 #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define ...

  4. loj#6040. 「雅礼集训 2017 Day5」矩阵(线性代数+递推)

    题面 传送门 题解 我的线代学得跟屎一样看题解跟看天书一样所以不要指望这题我会写题解 这里 //minamoto #include<bits/stdc++.h> #define R reg ...

  5. @loj - 6039@ 「雅礼集训 2017 Day5」珠宝

    目录 @description@ @solution@ @accpeted code@ @details@ @description@ Miranda 准备去市里最有名的珠宝展览会,展览会有可以购买珠 ...

  6. [LOJ#6039].「雅礼集训 2017 Day5」珠宝[决策单调性]

    题意 题目链接 分析 注意到本题的 \(C\) 很小,考虑定义一个和 \(C\) 有关的状态. 记 \(f(x,j)\) 表示考虑到了价格为 \(x\) 的物品,一共花费了 \(j\) 元的最大收益. ...

  7. loj #6039 「雅礼集训 2017 Day5」珠宝 分组背包 决策单调性优化

    LINK:珠宝 去年在某个oj上写过这道题 当时懵懂无知wa的不省人事 终于发现这个东西原来是有决策单调性的. 可以发现是一个01背包 但是过不了 冷静分析 01背包的复杂度有下界 如果过不了说明必然 ...

  8. loj6038「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目传送门 https://loj.ac/problem/6038 题解 根据树的直径的两个性质: 距离树上一个点最远的点一定是任意一条直径的一个端点. 两个联通块的并的直径是各自的联通块的两条直径的 ...

  9. 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...

随机推荐

  1. 后端API入门到放弃指北

    后端API入门学习指北 了解一下一下概念. RESTful API标准] 所有的API都遵循[RESTful API标准]. 建议大家都简单了解一下HTTP协议和RESTful API相关资料. 阮一 ...

  2. Javascript格式化并高亮xml字符串

    Javascript格式化并高亮xml字符串 两个关键点 使用DOMParser解析xml 递归遍历xml树,按格式输出每一个节点 关于使用DOMParser 此方法目前在IE9以上和其它浏览器里都是 ...

  3. 原生android(二)——认识activity

    一.activity的生命周期 1.onCreate():在活动第一次被创建的时候调用,用来完成活动的初始化操作,如加载布局.绑定事件等 2.onStart():在活动由不可见变为可见时被调用 3.o ...

  4. Mac下布置appium环境

    1.下载或者更新Homebrew:homebrew官网 macOS 不可或缺的套件管理器 $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githu ...

  5. 创建第一个Scrapy项目

    d:进入D盘 scrapy startproject tutorial建立一个新的Scrapy项目 工程的目录结构: tutorial/ scrapy.cfg # 部署配置文件 tutorial/ # ...

  6. MAC下Android的Eclipse开发环境搭建

    原文链接:https://www.cnblogs.com/macro-cheng/archive/2011/09/30/android-001.html 一.Eclipse的下载 到网站:http:/ ...

  7. 【win10系统问题】远程桌面登录一次后,第二次登录看不到用户名和密码输入框

    [win10系统远程桌面登录问题] 远程桌面登录某服务器一次后,第二次登录看不到用户名和密码输入框 [解决方法] 在注册表里找到该路径下的远程服务器ip,删除即可: HKEY_CURRENT_USER ...

  8. 2018软工实践—Alpha冲刺(1)

    o## 队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作,对多个目标检测及文字识别模型进行评估.实验 ...

  9. 利用p4实现ipv6转发实验

    写在前面 只是作为一个入门p4的实验尝试,借用了一些即成的运行代码. p4代码 /**p4_16,v1_model**/ #include<core.p4> #include<v1m ...

  10. A9

    今日内容: 解决队友提出的问题 明日计划: 商讨界面还有哪些不足的地方 困难: 每天大部分时间被电工实习占走了