博客
关于我
【LCT】P2147 [SDOI2008]洞穴勘测
阅读量:293 次
发布时间:2019-03-03

本文共 3125 字,大约阅读时间需要 10 分钟。

LCT(链接集合树)是一种高效的数据结构,广泛应用于处理各种树状结构的操作问题。以下是基于LCT的实现代码解析与应用示例。

代码结构分析:

  • 数据结构定义

    • 使用二叉树结构表示节点,每个节点包含父指针、左右子树指针以及逆序标记。
    • 树的大小限制为maxn,每个节点初始化时父指针、左右子树指针以及逆序标记都初始化为0。
  • 操作函数

    • isroot:判断一个节点是否为根节点。
    • rev:交换子树方向,并翻转逆序标记。
    • pushdown:将当前节点的子树操作下放到子节点。
    • rotate:旋转节点,使其成为新的根节点。
    • splay:通过旋转操作使树深度减少,提高操作效率。
    • access:通过路径压缩找到目标节点。
    • makeroot:将某个节点设置为根节点,并进行逆序调整。
    • findroot:找到当前树的根节点。
    • link:将两个树连接,形成新的树结构。
    • cut:将两个树分开,确保无环。
  • 代码应用示例:

    #include 
    using namespace std;const int maxn = 2e5;int n, m;struct LCT { struct node { int fa, ch[2], rev; node() { fa = ch[0] = ch[1] = rev = 0; } } tree[maxn]; int top, res[maxn]; #define ls(x) tree[x].ch[0] #define rs(x) tree[x].ch[1] int isroot(int x) { return tree[x].fa && (ls(tree[x].fa) == x || rs(tree[x].fa) == x); } void rev(int x) { swap(ls(x), rs(x)); tree[x].rev ^= 1; } void pushdown(int x) { if (!tree[x].rev) return; if (ls(x)) rev(ls(x)); if (rs(x)) rev(rs(x)); tree[x].rev ^= 1; } void rotate(int x) { int y = tree[x].fa, z = tree[y].fa; int k = (x == ls(tree[x].fa)), w = tree[x].ch[k]; if (isroot(y)) tree[z].ch[y == rs(tree[y].fa)] = x; tree[x].ch[k] = y; tree[y].ch[!k] = w; tree[y].fa = x; tree[x].fa = z; if (w) tree[w].fa = y; } void splay(int x) { int tmp = x; res[top = 1] = tmp; while (isroot(tmp)) { res[++top] = tree[tmp].fa; tmp = tree[tmp].fa; } while (top) { pushdown(res[top]); top--; } while (isroot(x)) { if (isroot(tree[x].fa)) { int k = (x == rs(tree[x].fa)) ^ (tree[x].fa == rs(tree[tree[x].fa].fa)); rotate(k ? tree[x].fa : x); } rotate(x); } } void access(int x) { for (int y = 0; x; x = tree[x].fa) { splay(x); rs(x) = y; } } void makeroot(int x) { access(x); splay(x); rev(x); } int findroot(int x) { access(x); splay(x); while (ls(x)) { pushdown(x); x = ls(x); pushdown(x); } return x; } void link(int x, int y) { if (findroot(x) == findroot(y)) return; makeroot(x); tree[x].fa = y; } void cut(int x, int y) { makeroot(x); access(y); splay(y); if (ls(y) == x) { tree[x].fa = ls(y) = 0; } }} LCT;int main() { freopen("a.in", "r", stdin); freopen("a.out", "w", stdout); scanf("%d%d", &n, &m); char op[20]; int x, y; for (int i = 1; i <= m; ++i) { scanf("%s", op); scanf("%d%d", &x, &y); if (op[0] == 'C') { LCT.link(x, y); } else if (op[0] == 'D') { LCT.cut(x, y); } else if (op[0] == 'Q') { if (LCT.findroot(x) == LCT.findroot(y)) { printf("Yes\n"); } else { printf("No\n"); } } } return 0;}

    以上代码实现了一个高效的LCT结构,支持常规的树操作,如连接、切割以及根节点查询等功能。通过路径压缩和旋转操作,LCT显著提升了树操作的效率,使得复杂度接近线性。

    转载地址:http://idwm.baihongyu.com/

    你可能感兴趣的文章
    pg数据库中两个字段相除
    查看>>
    PhalApi:[1.23] 请求和响应:GET和POST两者皆可得及超越JSON格式返回
    查看>>
    Phalcon环境搭建与项目开发
    查看>>
    Phantom.js维护者退出,项目的未来成疑
    查看>>
    Pharmaceutical的同学们都看过来,关于补码运算的复习相关内容
    查看>>
    Phoenix 查看表信息及修改元数据
    查看>>
    Phoenix基础命令_视图映射和表映射_数字存储问题---大数据之Hbase工作笔记0036
    查看>>
    phoenix无法连接hbase shell创建表失败_报错_PleaseHoldException: Master is initializing---记录020_大数据工作笔记0180
    查看>>
    Phoenix简介_安装部署_以及连接使用---大数据之Hbase工作笔记0035
    查看>>
    phoenix连接hbase报错Can not resolve hadoop120, please check your network_记录026---大数据工作笔记0187
    查看>>
    Photoshop工作笔记001---Photoshop常用快捷键总结
    查看>>
    Reids配置文件redis.conf中文详解
    查看>>
    Photoshop脚本入门
    查看>>
    PHP
    查看>>
    Regular Expression Notes
    查看>>
    PHP $FILES error码对应错误信息
    查看>>
    PHP $_FILES函数详解
    查看>>
    PHP $_SERVER['HTTP_REFERER'] 获取前一页面的 URL 地址
    查看>>
    php &amp; 和 &amp;amp; (主要是url 问题)
    查看>>
    php -- 魔术方法 之 判断属性是否存在或为空:__isset()
    查看>>