考虑\(LCT\)

不难发现,我们不需要换根...

对于操作\(1\),\(splay(u)\)然后连虚边即可

对于操作\(3\),我们可以先\(access(u)\),然后再\(access(v)\),然后查最后一个虚边变实边的点

对于操作\(2\)

可以选择\(access(u), splay(u)\),然后从\(u\)所在的\(splay\)中删去\(u\)点

也可以选择\(access(u), access(v), splay(u)\),这时,边\((u, v)\)成为虚边,十分好删除

复杂度\(O(n \log n)\)


版本1:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;#define ri register int
#define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
#define drep(io, ed, st) for(ri io = ed; io >= st; io --)#define gc getchar
inline int read() {int p = 0, w = 1; char c = gc();while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();return p * w;
}const int sid = 1e5 + 5;int n, m;
char s[sid];
int son[sid][2], fa[sid], pra[sid];#define ls(o) son[(o)][0]
#define rs(o) son[(o)][1]inline bool isrc(int o) { return rs(fa[o]) == o; }
inline bool isr(int o) { return !fa[o] || (ls(fa[o]) != o && rs(fa[o]) != o); }inline void rotate(int o) {int f = fa[o], g = fa[f];int ro = isrc(o), rf = isrc(f), p = son[o][ro ^ 1];if(!isr(f)) son[g][rf] = o; son[o][ro ^ 1] = f; son[f][ro] = p;fa[p] = f; fa[f] = o; fa[o] = g;
}inline void splay(int o) {while(!isr(o)) {int f = fa[o];if(!isr(f)) rotate(isrc(f) == isrc(o) ? f : o);rotate(o);}
}int lca = 0;
inline void access(int o) {int lst = 0;while(o) {splay(o); rs(o) = lst;lca = lst = o; o = fa[o];}
}int main() {n = read(); m = read();rep(i, 1, m) {int u, v;scanf("%s", s);if(s[1] == 'i') {u = read(); v = read();splay(u); pra[u] = v; fa[u] = v;}else if(s[1] == 'c') {u = read(); v = read();access(u); access(v);printf("%d\n", lca);}else if(s[1] == 'u') {u = read();access(u); access(pra[u]);splay(u); fa[u] = 0;}}return 0;
}

版本\(2\):

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;#define ri register int
#define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
#define drep(io, ed, st) for(ri io = ed; io >= st; io --)#define gc getchar
inline int read() {int p = 0, w = 1; char c = gc();while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();return p * w;
}const int sid = 1e5 + 5;int n, m;
char s[sid];
int son[sid][2], fa[sid], pra[sid];#define ls(o) son[(o)][0]
#define rs(o) son[(o)][1]inline bool isrc(int o) { return rs(fa[o]) == o; }
inline bool isr(int o) { return !fa[o] || (ls(fa[o]) != o && rs(fa[o]) != o); }inline void rotate(int o) {int f = fa[o], g = fa[f];int ro = isrc(o), rf = isrc(f), p = son[o][ro ^ 1];if(!isr(f)) son[g][rf] = o; son[o][ro ^ 1] = f; son[f][ro] = p;fa[p] = f; fa[f] = o; fa[o] = g;
}inline void splay(int o) {while(!isr(o)) {int f = fa[o];if(!isr(f)) rotate(isrc(f) == isrc(o) ? f : o);rotate(o);}
}int lca = 0;
inline void access(int o) {int lst = 0;while(o) {splay(o); rs(o) = lst;lca = lst = o; o = fa[o];}
}int main() {n = read(); m = read();rep(i, 1, m) {int u, v;scanf("%s", s);if(s[1] == 'i') {u = read(); v = read();splay(u); pra[u] = v; fa[u] = v;}else if(s[1] == 'c') {u = read(); v = read();access(u); access(v);printf("%d\n", lca);}else if(s[1] == 'u') {u = read();access(u); splay(u);ls(u) = fa[ls(u)] = 0;}}return 0;
}

转载于:https://www.cnblogs.com/reverymoon/p/10091974.html

SPOJ8791 DYNALCA LCT相关推荐

  1. 2019.03.01 bzoj2555: SubString(sam+lct)

    传送门 题意简述: 要求在线支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 思路: 考虑用lctlctlct来动态维护samsa ...

  2. 洛谷.4234.最小差值生成树(LCT)

    题目链接 先将边排序,这样就可以按从小到大的顺序维护生成树,枚举到一条未连通的边就连上,已连通则(用当前更大的)替换掉路径上最小的边,这样一定不会更差. 每次构成树时更新答案.答案就是当前边减去生成树 ...

  3. bzoj 4025 二分图——线段树分治+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...

  4. BZOJ2631tree——LCT

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...

  5. BZOJ 4817: [Sdoi2017]树点涂色(LCT+树剖+线段树)

    题目描述 Bob有一棵 nn 个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. Bob ...

  6. 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]

    树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MB [Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中 ...

  7. UOJ #274. 【清华集训2016】温暖会指引我们前行 [lct]

    #274. [清华集训2016]温暖会指引我们前行 题意比较巧妙 裸lct维护最大生成树 #include <iostream> #include <cstdio> #incl ...

  8. 【bzoj5020】[THUWC 2017]在美妙的数学王国中畅游 泰勒展开+LCT

    题目描述 学渣小R被大学的数学课程虐得生活不能自理,微积分的成绩曾是他在教室里上的课的最低分.然而他的某位陈姓室友却能轻松地在数学考试中得到满分.为了提升自己的数学课成绩,有一天晚上(在他睡觉的时候) ...

  9. bzoj3514(LCT+主席树)

    题目描述 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解 对于一个截止时间来说,越晚的变越好. 所以我们可以维护一颗以边的序号为关键字的最大生成树,然后用主席树维 ...

  10. BZOJ 4679/Hdu5331 Simple Problem LCT or 树链剖分

    4679: Hdu5331 Simple Problem 题意: 考场上,看到这道题就让我想起BZOJ4712洪水.然后思路就被带着飞起了,完全没去考虑一条链的情况,于是GG. 解法:先考虑一条链的做 ...

最新文章

  1. java pdf插件下载_免费java pdf控件
  2. 国内外有哪些不错的需求管理工具?如何选择?
  3. flask_sqlalchemy 多对多重复插入解决办法
  4. java同步变异步框架_java-如何使用Spring配置异步和同步事件发布者
  5. python 无法引入同级目录的方法_再见 virtualenv!K神教你轻松管理多个Python环境...
  6. python列表存储乱码_python 列表中文乱码
  7. delphi设计模式 多语言开发
  8. 傅里叶变换 【完整版】
  9. c语言共享内存储存结构体,C语言共享内存使用思路利用结构体
  10. C++自定义sort排序
  11. 邮件管理数据库设计--MySQL
  12. el-table点击单元格自动聚焦可编辑,且失去焦点即修改成功的实现方法
  13. 通过财务报表读懂美股
  14. 【word】删除页眉横线
  15. 计算机小写换大写函数,excel小写换大写函数的教程
  16. Adobe Acrobat 如何通过书签制作多级目录
  17. 第三方包的安装及管理
  18. apifox设置全局header
  19. Java工程师进阶知识完全扫盲, 太全了!!
  20. 进制之间的转换(计算机系统基础)

热门文章

  1. 我的天!你竟然没有在SpringBoot中使用过异步请求和异步调用...
  2. Java虚拟机最多支持多少个线程?
  3. 大型网站技术架构的原理与分析
  4. mysql 单精度和双经度,mysql – 计算距离给定2点,纬度和经度
  5. Volatile关键字,你真的理解吗?
  6. BZOJ4998 星球联盟(LCT+双连通分量+并查集)
  7. Redis学习-1 NoSQL
  8. UVALive - 7267 Mysterious Antiques in Sackler Museum
  9. 菜鸟 学注册机编写之 “序列号组合”
  10. 雇员查询java面试题经典29例【第八季_常瑞鹏】