\(\color{#0066ff}{ 题目描述 }\)

有一个森林最初由 n (\(1 \le n \le 100000\))n(\(1\leq n\leq 100000\)) 个互不相连的点构成

你需要处理以下操作:

link A B:添加从顶点A到B的边,使A成为B的子节点,其中保证A是一个根顶点,A和B在不同的树中。

cut A:切断点A到其父节点的边,保证A是一个非根节点。

lca A B:输出A和B的最近共同祖先,保证A和B在同一棵树中。

\(\color{#0066ff}{输入格式}\)

第一行包含三个正整数N、M,分别表示树的结点个数、询问的个数

接下来M行表示询问。

\(\color{#0066ff}{输出格式}\)

对于每个LCA询问输出答案

\(\color{#0066ff}{输入样例}\)

5 9
lca 1 1
link 1 2
link 3 2
link 4 3
lca 1 4
lca 3 4
cut 4
link 5 3
lca 1 5

\(\color{#0066ff}{输出样例}\)

1
2
3
2

\(\color{#0066ff}{数据范围与提示}\)

none

\(\color{#0066ff}{ 题解 }\)

LCT求LCA

cut的时候,因为删的是父子边,暴力找前驱就行了

#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL in() {
char ch; int x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 1e5 + 5;
struct LCT {
protected:
struct node {
node *ch[2], *fa;
int rev;
node(int rev = 0): rev(rev) { ch[0] = ch[1] = fa = NULL; }
bool ntr() { return fa && (fa->ch[1] == this || fa->ch[0] == this); }
bool isr() { return fa->ch[1] == this; }
void trn() { std::swap(ch[0], ch[1]); rev ^= 1; }
void dwn() { if(rev) { if(ch[0]) ch[0]->trn(); if(ch[1]) ch[1]->trn(); rev = 0; } }
}s[maxn], *lst, *t[maxn];
int top, fa[maxn];
void rot(node *x) {
node *y = x->fa, *z = y->fa; int k = x->isr(); node *w = x->ch[!k];
if(y->ntr()) z->ch[y->isr()] = x;
x->ch[!k] = y, y->ch[k] = w;
y->fa = x, x->fa = z;
if(w) w->fa = y;
}
void splay(node *o) {
t[top = 1] = o;
while(t[top]->ntr()) t[top + 1] = t[top]->fa, top++;
while(top) t[top--]->dwn();
while(o->ntr()) { if(o->fa->ntr()) rot(o->isr() ^ o->fa->isr()? o : o->fa); rot(o); }
}
void access(node *x) { for(node *y = NULL; x; x = (y = x)->fa) splay(x), x->ch[1] = y, lst = x; }
void makeroot(node *x) { access(x), splay(x), x->trn(); }
node *findroot(node *x) {
access(x), splay(x);
while(x->dwn(), x->ch[0]) x = x->ch[0];
return splay(x), x;
}
void link(node *x, node *y) { makeroot(x), x->fa = y; }
node *pre(node *x) {
access(x), splay(x); x->dwn(), x = x->ch[0];
while(x->dwn(), x->ch[1]) x = x->ch[1];
return splay(x), x;
}
void cut(node *x) {
access(x), splay(x), x->dwn();
node *y = x->ch[0];
while(y->dwn(), y->ch[1]) y = y->ch[1];
splay(y);
y->ch[1] = x->fa = NULL;
}
public:
int LCA(int x, int y) { return access(s + x), access(s + y), lst - s; }
void link(int x, int y) { link(s + x, s + y); }
void cut(int x) { cut(s + x); }
}v;
char getch() {
char ch;
while(!isalpha(ch = getchar()));
return ch;
}
int main() {
int n = in(), m = in();
int x, y;
while(m --> 0) {
if(getch() == 'l') {
if(getch() == 'c') x = in(), y = in(), printf("%d\n", v.LCA(x, y));
else x = in(), y = in(), v.link(x, y);
}
else v.cut(in());
}
return 0;
}

SP8791 DYNALCA - Dynamic LCA的更多相关文章

  1. SP8791 DYNALCA - Dynamic LCA 解题报告

    SP8791 DYNALCA - Dynamic LCA 有一个森林最初由 \(n (1 \le n \le 100000)\) 个互不相连的点构成 你需要处理以下操作: link A B:添加从顶点 ...

  2. 【题解】Luogu SP8791 DYNALCA - Dynamic LCA

    原题传送门 这题用Link-Cut-Tree解决,Link-Cut-Tree详解 这道题的难点就在如何求LCA: 我们珂以先对其中一个点进行access操作,然后对另一个点进行access操作,因为L ...

  3. spoj DYNALCA - Dynamic LCA

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

  4. CodeForcesGym 100512D Dynamic LCA

    Dynamic LCA Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForcesGym. ...

  5. 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )

    在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...

  6. P6845 [CEOI2019] Dynamic Diameter

    P6845 [CEOI2019] Dynamic Diameter 题意 一颗带权树,每次更改一条边的权,每次修改后求出最大直径.强制在线. 思路 \(O(n\log^2n)\) 的暴力做法. 根据经 ...

  7. var和dynamic的区别

    1.var 1.均是声明动态类型的变量. 2.在编译阶段已经确定类型,在初始化的时候必须提供初始化的值. 3.无法作为方法参数类型,也无法作为返回值类型. 2.dynamic 1.均是声明动态类型的变 ...

  8. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  9. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

随机推荐

  1. 2015.1.3 DataGridView中嵌入其它控件

    1.按正常方法绑定待嵌入列的值,先赋值为空也行. 2.添加combbox到datagrivdview中 dvaw.Controls.Add(cb_dir); 3.添加DataGridView Mous ...

  2. Changing Controller Numbers in Solaris

    If you need to change the controller numbers (c#) that a disk has assigned to it, whether it is for ...

  3. 10-26C#基础回顾、汇总(函数重点)

    第一部分==进制转换 重点记忆: 1.任意进制转十进制 按权展开法 p代表进制数,a/b/c...m分别代表进制数p从右往左第1位--第(n-1)位的数 公式:a*p0+b*p1+c*p2+..... ...

  4. bash: telnet: command not found

    //安装telnet服务 yum -y install telnet-server //安装telnet客户端 yum -y install telnet.*

  5. CentOS6.5 增加交换空间

    在CentOS 6.5安装Oracle 11g的时候,提示交换空间不足,百度来下,找到来增加交换空间的方法,特此记录一下 增加交换空间有两种方法: 严格的说,在系统安装完后只有一种方法可以增加swap ...

  6. 如何边遍历集合边删除元素--使用Iterator中的remove()方法

    在遍历集合时,想将符合条件的某些元素删除,开始是用了下面的方法 public static void main(String[] args) throws UnsupportedEncodingExc ...

  7. struts2学习笔记(5)拦截器

    继承AbstractInterceptor类,在类中完成拦截器的功能,只需实现intercept方法即可,提供了init()和destroy()的空实现 示例:显示执行action所用的时间 ①在sr ...

  8. Ros学习——创建ROS消息和ROS服务

    1.rosed rosed 是 rosbash 的一部分.利用它可以直接通过package名来获取到待编辑的文件而无需指定该文件的存储路径了. rosed默认的编辑器是vim.修改其他的,打开~/.b ...

  9. 基于GStreamer编写Mp3播放器

    一.简介 作者系统为CentOS6,本文在此基础上对Mp3播放器进行开发,需要使用mp3解码库libmad和gstreamer0.10-plugins-ugly,详细步骤如下.   二.操作步骤 1) ...

  10. 100197G Robbers

    传送门 题目大意 看式子懂题意系列... 分析 自然想到我们先按比例下取整得到一个值,再按每个人这样分配所产生的值从大到小排序,然后将剩下的几个金币自大到小每人分配一个,代码挺好理解的,详见代码. 代 ...