\(\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. MySQL mysqldump 备份脚本(按照db.sql)

    mysqldump逻辑备份,按照db.sql文件区分,并压缩 #! /bin/bash #35 02 * * * mysql /data/mysqldata/scripts/mysqldump_per ...

  2. delphi 安卓配置教程

    本教程以 delphi 10.2.2.2004 为例,演示 delphi 安卓配置步骤 1.打开 Android Tools 2. 选择合适的版本.比如:我的小米4 LTE 是 andorid 6.0 ...

  3. Beautiful Soup 4.2.0

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式 快速开始 pip install beaut ...

  4. vi,sed,tr,awk技巧

    将文件中的换行替换为逗号 使用sed: sed -e :a -e N -e '$!ba' -e 's/\n/,/g' filename 使用tr: cat filename | tr '\n' ',' ...

  5. NSFileManager和NSFileHandle使用

    一.NSFileManager: 1.1.获取NSFileManager NSFileManager *manager = [NSFileManager defaultManager];     NS ...

  6. css代码结构

    整个文档结构如下: 一般性样式 主体样式 reset样式 链接 标题 其他元素 辅助样式 表单 通知和错误 一致的条目 页面结构 标题.页脚和导航 布局 其他页面结构元素 页面组件 各个页面 覆盖

  7. Ros学习service——小海龟

    rosservice 服务(services)是节点之间通讯的另一种方式.服务允许节点发送请求(request) 并获得一个响应(response) rosservice list 输出可用服务的信息 ...

  8. python常用uuid模块

    uuid.uuid4(),会根据我们当前的网卡和时间生成的一个随机字符串. 注意:uuid.uuid4()生成的是一个对象,需要强转为字符串. uid = str(uuid.uuid4()) #当前网 ...

  9. 选择设置好ext3日志模式

    Linux是一种开放的.因Internet而产生的操作系统.Internet的发展.以网络为中心的计算模式如电子商务被迅速接受和普及,都为 Linux提供了更巨大的机会,使之成为企业和部门级的首选平台 ...

  10. 算法导论 寻找第i小元素 9.2

    PS1:如果单纯为做出这道题那么这个代价是O(nlgn),通过排序就可以了. 这里讨论的是O(n)的算法.那么来分析一下这个算法是如何做到O(n)的,算了不分析了,这个推到看起来太麻烦了.其实我想知道 ...