考虑\(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;
}

SPOJ8791 DYNALCA LCT的更多相关文章

  1. spoj DYNALCA - Dynamic LCA

    http://www.spoj.com/problems/DYNALCA/ 此题link.cut要求不能换根,当然也保证link时其中一个点必定已经是根. 方法: void link(Node *x, ...

  2. 一堆LCT板子

    搞了一上午LCT,真是累死了-- 以前总觉得LCT高大上不好学不好打,今天打了几遍感觉还可以嘛= =反正现在的水平应付不太难的LCT题也够用了,就这样好了,接下来专心搞网络流. 话说以前一直YY不出来 ...

  3. 动态树之LCT(link-cut tree)讲解

    动态树是一类要求维护森林的连通性的题的总称,这类问题要求维护某个点到根的某些数据,支持树的切分,合并,以及对子树的某些操作.其中解决这一问题的某些简化版(不包括对子树的操作)的基础数据结构就是LCT( ...

  4. 在此为LCT开一个永久的坑

    其实我连splay都还不怎么会. 今天先抄了黄学长的bzoj2049,以后一定要把它理解了. 写LCT怎么能不%数据结构大神yeweining呢?%%%chrysanthemums  %%%切掉大森林 ...

  5. 【BZOJ2157】旅游 LCT

    模板T,SB的DMoon..其实样例也是中国好样例...一开始不会复制,yangyang:找到“sample input”按住shift,按page down.... #include <ios ...

  6. 【BZOJ3669】[Noi2014]魔法森林 LCT

    终于不是裸的LCT了...然而一开始一眼看上去这是kruskal..不对,题目要求1->n的路径上的每个点的两个最大权值和最小,这样便可以用LCT来维护一个最小生成路(瞎编的...),先以a为关 ...

  7. 【BZOJ1180】: [CROATIAN2009]OTOCI & 2843: 极地旅行社 LCT

    竟然卡了我....忘记在push_down先下传父亲的信息了....还有splay里for():卡了我10min,但是双倍经验还是挺爽的,什么都不用改. 感觉做的全是模板题,太水啦,不能这么水了... ...

  8. 【BZOJ3282】Tree LCT

    1A爽,感觉又对指针重怀信心了呢= =,模板题,注意单点修改时splay就好,其实按吾本意是没写的也A了,不过应该加上能更好维护平衡性. ..还是得加上好= = #include <iostre ...

  9. BZOJ2888 资源运输(LCT启发式合并)

    这道题目太神啦! 我们考虑他的每一次合并操作,为了维护两棵树合并后树的重心,我们只好一个一个的把节点加进去.那么这样一来看上去似乎就是一次操作O(nlogn),但是我们拥有数据结构的合并利器--启发式 ...

随机推荐

  1. C# Func的同步、异步调用

    using System; namespace ActionDemo { class Program { static void Main(string[] args) { Console.Write ...

  2. aarch64_o1

    OCE-devel-0.18.1-1.fc26.aarch64.rpm 2017-05-16 03:37 5.4M fedora Mirroring Project OCE-draw-0.18.1-1 ...

  3. aarch64_m1

    MAKEDEV-3.24-18.fc26.aarch64.rpm 2017-02-14 08:46 99K fedora Mirroring Project MUMPS-5.0.2-8.fc26.aa ...

  4. Mac下破解intellij IDEA 2018

    一.在进入下面网站下载破解补丁 http://idea.lanyus.com/ 二.在“应用程序”中找到已经安装的IntelliJ IDEA,在app上右键,选择“显示包内容”,如下图: 将下载的破解 ...

  5. Mac 升级一次,php 就崩溃一次,有味,苹果....

    Mac升级系统macOS Sierra后PHP不编译 Mac下搭建PHP开发环境(Apache+PHP+MySQL+phpMyAdmin),当Mac 从OS 10.11升级至macOS Sierra( ...

  6. MySQL触发器Trigger实例篇

    定义: 何为MySQL触发器? 在MySQL Server里面也就是对某一个表的一定的操作,触发某种条件(Insert,Update,Delete 等),从而自动执行的一段程序.从这种意义上讲触发器是 ...

  7. vue项目下使用iview总结

    iview在IE浏览器下有问题,打开页面是空白

  8. KVM virsh常用命令篇

    1.查看运行的虚拟机 virsh list 2.查看所有的虚拟机(关闭和运行的虚拟机) virsh list --all 3.连接虚拟机 virsh console +域名(虚拟机的名称) 4.退出虚 ...

  9. No.10 selenium学习之路之通过元素定位获取属性

    1. implicitly_wait()隐形等待.等待页面加载完成,作用是全局的. 时间可以设置的长,短时间也没有影响.直到设置的时间耗完 时间耗完也不会报错 2.获取title值 driver.ti ...

  10. 洛谷P2149 Elaxia的路线

    传送门啦 分析: 我最开始想的是跑两遍最短路,然后记录一下最短路走了哪些边(如果有两条最短路就选经过边多的),打上标记.两边之后找两次都标记的边有多少就行了. 但...我并没有实现出来. 最后让我们看 ...