洛谷题目传送门

太弱了不会树剖,觉得LCT好写一些,就上LCT乱搞,当LCT维护双连通分量的练手题好了

正序删边是不好来维护连通性的,于是就像水管局长那样离线处理,逆序完成操作

显然,每个点可以代表一个双连通分量,查询就是链的长度-1

连接一条边,如果在LCT中还没连通就link,如果连通了,显然这里会出现一个环,然后暴力缩点,可以把当前辅助树的根节点当做集合的标志节点,然后dfs整个辅助树,把链上的其它点的并查集祖先暴力改成这个标志节点,最后再断开标志节点与子树的连接。总的暴力修改次数不会超过\(N\log N\)次,复杂度是对的

但是点缩完了,那它们的子树不会指空吗?所以,access的时候,要更新\(x\)为\(geth(f[x])\)

至于常数,LCT也并不是很慢啊。反正有了O2还是可以做到很优秀的

代码细节很多,调试真心累TAT

#include<cstdio>
#include<algorithm>
using namespace std;
#define RG register
#define R RG short
#define I inline void
#define IB inline bool
#define IS inline short
#define G ch=getchar()
#define lc c[x][0]
#define rc c[x][1]
const int N=30009,M=100009;
short f[N],c[N][2],s[N],h[N],a[N],b[N],op[N],ans[M];
bool r[N],vis[M];
struct EDGE{//对边排序,方便查找该边是否被删除
short x,y;
IB operator<(const EDGE a)const{
return x<a.x||(x==a.x&&y<a.y);
}
}e[M];
template<typename T>
I in(RG T&z){
RG char G;
while(ch<'-')G;
z=ch&15;G;
while(ch>'-')z*=10,z+=ch&15,G;
}
IS geth(R x){
if(x==h[x])return x;
return h[x]=geth(h[x]);
}
IB nroot(R x){
return c[f[x]][0]==x||c[f[x]][1]==x;
}
I pushup(R x){
s[x]=s[lc]+s[rc]+1;
}
I pushdown(R x){
if(r[x]){
swap(lc,rc);
r[lc]^=1;r[rc]^=1;r[x]=0;
}
}
I pushall(R x){
if(nroot(x))pushall(f[x]);
pushdown(x);
}
I rotate(R x){
R y=f[x],z=f[y],k=c[y][1]==x,w=c[x][!k];
if(nroot(y))c[z][c[z][1]==y]=x;f[x]=z;
c[x][!k]=y;f[y]=x;
c[y][k]=w;f[w]=y;
pushup(y);
}
I splay(R x){
pushall(x);
R y;
while(nroot(x)){
if(nroot(y=f[x]))
rotate((c[f[y]][0]==y)^(c[y][0]==x)?x:y);
rotate(x);
}
pushup(x);
}
I access(R x){
for(R y=0;x;y=x,x=f[y]=geth(f[x]))//注意更新
splay(x),rc=y,pushup(x);
}
I makeroot(R x){
access(x);splay(x);
r[x]^=1;
}
IS findroot(R x){
access(x);splay(x);
pushdown(x);
while(lc)pushdown(x=lc);
splay(x);
return x;
}
I split(R x,R y){
makeroot(y);
access(x);splay(x);
}
I del(R x,R y){//函数递归缩点
if(x)h[x]=y,del(lc,y),del(rc,y);
}
I merge(R x,R y){
if(x==y)return;//在一个分量里什么都不用干
makeroot(x);
if(findroot(y)!=x){
f[x]=y;return;//等于link
}
del(rc,x);
rc=0;pushup(x);//缩点,删点
}
int main(){
RG int n,m,i,j;
R x,y;
in(n);in(m);
for(i=1;i<=n;++i)s[i]=1,h[i]=i;
for(i=1;i<=m;++i){
in(x);in(y);
if(x>y)swap(x,y);//强制编号,方便以后查找
e[i]=(EDGE){x,y};
}
sort(e+1,e+m+1);
for(j=1;in(op[j]),op[j]!=131;++j){
in(x);in(y);
if(!op[j]){
if(x>y)swap(x,y);
vis[lower_bound(e+1,e+m+1,(EDGE){x,y})-e]=1;
}//重载完小于号,直接二分找到,再打上删除记号
a[j]=x;b[j]=y;
}
for(i=1;i<=m;++i)
if(!vis[i])merge(geth(e[i].x),geth(e[i].y));
for(i=0,--j;j;--j){
x=geth(a[j]);y=geth(b[j]);
if(op[j])split(x,y),ans[++i]=s[x]-1;
else merge(x,y);
}
while(i)printf("%hd\n",ans[i--]);
return 0;
}

洛谷P2542 [AHOI2005]航线规划(LCT,双连通分量,并查集)的更多相关文章

  1. 洛谷 P2542 [AHOI2005]航线规划 解题报告

    P2542 [AHOI2005]航线规划 题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系--一个巨大的由千百万星球构成的Samuel星系 ...

  2. 洛谷 P2542 [AHOI2005]航线规划(Link-cut-tree)

    题面 洛谷 bzoj 题解 离线处理+LCT 有点像星球大战 我们可以倒着做,断边变成连边 我们可以把边变成一个点 连边时,如果两个点本身不联通,就\(val\)赋为\(1\),并连接这条边 如果,两 ...

  3. 洛谷 P2542 [AHOI2005]航线规划 树链剖分_线段树_时光倒流_离线

    Code: #include <map> #include <cstdio> #include <algorithm> #include <cstring&g ...

  4. P2542 [AHOI2005]航线规划 LCT维护双连通分量

    \(\color{#0066ff}{ 题目描述 }\) 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系--一个巨大的由千百万星球构成的Samuel ...

  5. BZOJ4998 星球联盟(LCT+双连通分量+并查集)

    即要求动态维护边双.出现环时将路径上的点合并即可.LCT维护.具体地,加边成环时makeroot+access+splay一套把这段路径提出来,暴力dfs修改并查集祖先,并将这部分与根断开,视为删除这 ...

  6. BZOJ 2959: 长跑 [lct 双连通分量 并查集]

    2959: 长跑 题意:字词加入边,修改点权,询问两点间走一条路径的最大点权和.不一定是树 不是树

  7. 洛谷P2661 信息传递(最小环,并查集)

    洛谷P2661 信息传递 最小环求解采用并查集求最小环. 只适用于本题的情况.对于新加可以使得两个子树合并的边,总有其中一点为其中一棵子树的根. 复杂度 \(O(n)\) . #include< ...

  8. [AHOI2005]航线规划——LCT维护边双联通分量

    因为只能支持加入一个边维护边双,所以时光倒流 维护好边双,每次就是提取出(x,y)的链,答案就是链长度-1 具体维护边双的话, void access(int x){ for(reg y=0;x;y= ...

  9. 洛谷OJ P1196 银河英雄传说(带权并查集)

    题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...

随机推荐

  1. nodejs开发调试时,使用supervisor

    如果你有 PHP 开发经验,会习惯在修改 PHP 脚本后直接刷新浏览器以观察结果,而你在开发 Node.js 实现的 HTTP 应用时会发现,无论你修改了代码的哪一部份,都必须终止Node.js 再重 ...

  2. Xcode添加全局引用文件pch

    Xcode6之前有PrefixHeader.pch文件在写项目的时候,大部分宏定义.头文件都导入在这个pch文件,虽然方便,但会增加Build的时间,所以Xcode6以及之后的版本去除了PrefixH ...

  3. Docker安装Python3.5

    方法一.通过 Dockerfile 构建 创建Dockerfile 首先,创建目录python,用于存放后面的相关东西. mkdir -p ~/python ~/python/myapp myapp目 ...

  4. BZOJ4999: This Problem Is Too Simple!树链剖分+动态开点线段树

    题目大意:将某个节点的颜色变为x,查询i,j路径上多少个颜色为x的点... 其实最开始一看就是主席树+树状数组+DFS序...但是过不去...MLE+TLE BY FCWWW 其实树剖裸的一批...只 ...

  5. EEPROM---AT24Cxx应用介绍

    结论:1.读写AT24CXX芯片,根据容量有多种方式:一.容量为AT24C01~AT24C16,首先发送设备地址(8位地址),再发送数据地址(8位地址),再发送或者接受数据. 二.AT24C32/AT ...

  6. Java容器类List、ArrayList、Vector及map、HashTable、HashMap的区别与用法

    Java容器类List.ArrayList.Vector及map.HashTable.HashMap的区别与用法 ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数 ...

  7. 微信小程序初体验与DEMO分享

    前言 前一段时间微信公布小程序,瞬间引来了大量的关注.博主的公司也将其定为目标之一,遂派本菜为先头兵(踩坑侠). 这次开发了一个比较完整的DEMO,模仿自某个APP首页,由于保护隐私的目的我把数据拷贝 ...

  8. linux之grep 基础

    第一章 -a    将binary文件以text文件的方式搜寻数据-c    只输出匹配行的计数,计算找到匹配的次数-I(大写i)    不区分大小写(只适合用于单字符)-h    查询多文件时不显示 ...

  9. python中类中属性和方法的具体定义方法和使用

    1. Python中类中特性分成属性和方法 属性和方法都分为私有和公有的,私有的只可以在本类中使用外部是无法访问的 2. 定义属性(成员变量)的语法格式(公有属性/私有属性) class 类名: de ...

  10. Intellij IDEA 2017 debug断点调试技巧与总结详解篇

    转载自csdn----------------------------------------------------------------------https://blog.csdn.net/q ...