首页 > 其他分享 >Splay/LCT 学习笔记

Splay/LCT 学习笔记

时间:2023-12-06 19:22:17浏览次数:28  
标签:LCT ch return int 笔记 Splay fa

唔,其实我不会 Splay,但是我会 LCT。

众所周知,会 LCT 和会 Splay 是两回事,因为 LCT 只需要旋至根即可。

到现在还是不会,但是先把 LCT 的 Splay 写一下吧。

自己复习用的。

先给代码。

LCT code
int isroot(int x) {return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
int idt(int x) {return ch[fa[x]][1]==x;}
void swp(int x) {
    if(!x) return ;
    rev[x]^=1;
    swap(ls,rs);
}
void pushdown(int x) {
    if(rev[x]) {
        rev[x]=0;
        swp(ls);
        swp(rs);
    }
}
void pushup(int x) {
    if(!x) return;
    if(x<=n) ma[x]=-INF;
    else ma[x]=val[x];
    if(ls) cmax(ma[x],ma[ls]);
    if(rs) cmax(ma[x],ma[rs]);
}
void pushall(int x) {
    if(!isroot(x)) pushall(fa[x]);
    pushdown(x);
}
void add(int y,int x,int i) {ch[fa[x]=y][i]=x;}
void rotate(int x) {
    int y=fa[x],i=idt(x);
    if(isroot(y)) fa[x]=fa[y];
    else add(fa[y],x,idt(y));
    add(y,ch[x][!i],i);
    add(x,y,!i);
    pushup(y);
}
void splay(int x) {
    pushall(x);
    for(int y;y=fa[x],!isroot(x);rotate(x)) {
        if(!isroot(y)) rotate(idt(x)==idt(y)?y:x);
    }
    pushup(x);
}
void access(int x) {
    for(int p=0;x;p=x,x=fa[x]) {
        splay(x);
        ch[x][1]=p;
        pushup(x);
    }
}
void makeroot(int x) {
    access(x);
    splay(x);
    swp(x);
}
void split(int u,int v) {
    makeroot(u);
    access(v);
    splay(u);
}
void cut(int u,int v) {
    split(u,v);
    ch[u][1]=fa[v]=0;
    pushup(u);
}
int findroot(int x) {
	access(x);
	splay(x);
	while(pushdown(x), ls) x = ls;
	splay(x);
}

主要就是下面这三个函数。分开讨论。

\(rotate\) 操作说明

因为 y = fa[x],那么有 x = ch[y][i]

旋转的过程即是先用 \(x\) 替换 \(y\),即从 fa[y] 的视角而言。

然后用 \(x, y\) 两点间“包夹”的子树替换 \(x\),即从 \(x, y\) 的包夹子树的视角而言。

最后将子树的位置用 \(y\) 替换,即从 \(x, y\) 间的视角而言。

\(splay\) 操作

这个主要是旋转方向的问题。

就是第一次有可能对父亲也有可能对自己,若自己与父亲呈一条线idt(y) == idt(x)则转父亲,此时是一个相对于 x <- fa[x] -> fa[fa[x]] 的较平衡形态 \(1\),否则转自己,此时是 fa[fa[x]]->x->fa[x] 的直线形态 \(2\)。

发现无论怎样都需要将 x 再次旋至根,若原来为 \(1\) 形态,旋转后会变成 x -> fa[x] - > fa[fa[x]] 的形态,若原来为 \(2\) 形态,则旋转后会变为 fa[fa[x]] <- x -> fa[x] 的较平衡形态。

对了,还有当前只有一层深度,此时只用旋转 x 即可。

那么这样的话无论怎样都会出现一次较平衡形态,所以可以保证复杂度。

当然,这样只是便于记忆罢了。

严谨的分析其实可以用势能分析法,OI-Wiki 上有,等我学成归来……

然后我们再分析只有单旋的,若开始前是直线状态,则单旋两次后不会出现较平衡形态,而是先出现一个折线,再出现一条直线。

若开始前为折线,则单旋两次后先出现一条直线,再出现一个较平衡状态。

是的,所以若开始前为直线则不能保证复杂度。

同样,这也不是严谨分析……

\(access\) 操作

将 \(x\) 与 原树上的根 之间的路径取出。

注意点:

  1. 操作完后 \(x\) 有实儿子,但是只会有左儿子,即原树的到根的链上的节点,所以得到的是一条从 根 到 \(x\) 的链,没有其他节点。

  2. pushup(x)

标签:LCT,ch,return,int,笔记,Splay,fa
From: https://www.cnblogs.com/SkyMaths/p/17838520.html

相关文章

  • 【数据结构】线段树 (二) 学习笔记
    线段树(二)点击查看:线段树(一)学习笔记本文介绍权值线段树与动态开点线段树,(可能后面还会加线段树合并等等)。权值线段树线段树的动态开点线段树合并推荐题目&&参考资料&&拓展阅读《算法竞赛进阶指南》0x43线段树P3870 [TJOI2009]开关P1438 无聊的数列P1253 扶苏的问......
  • 《Java编程思想第四版》学习笔记44--关于按钮组
    //:ButtonGroups.java//Usesreflectiontocreategroupsofdifferent//typesofAbstractButton.packagec13.swing;importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;importjavax.swing.border.*;importjava.lang.reflect.*;publicclassB......
  • 在MySql一个数据源的所有数据库中根据数据表注释查询数据表所属数据库以及表名_根据某
    Selecttable_schema'数据库名',table_name表名,TABLE_COMMENT'表注解'fromINFORMATION_SCHEMA.TABLESWhereTABLE_COMMENTLIKE'%环境监测%';selectTABLE_SCHEMA'数据库名',TABLE_NAME'表名',COLUMN_NAME'列名',CO......
  • Programming Abstractions in C阅读笔记:p196
    《ProgrammingAbstractionsinC》学习第63天,p196总结。涉及到编程之外的知识,依然是读起来很费劲,需要了解作者在书中提到的人物(EdouardLucas)、地点(Benares)、神话传说(Brahma)等等。虽然深知自己做不到对人文知识,历史知识精通,但也希望能记住,从而在下次遇到的时候能够阅读下去,......
  • 《REBEL Relation Extraction By End-to-end Language generation》阅读笔记
    论文来源 代码地址 相关视频(YouTube) 相关概念:1.Whatisnaturallanguageunderstanding(NLU)?Naturallanguageunderstanding(NLU)isabranchofartificialintelligence(AI)thatusescomputersoftwaretounderstandinputintheformofsentencesusin......
  • Flask ORM 学习笔记Part06:marshmallow的使用(下)
    前两篇学习笔记中讲了schema字段,验证器等。这篇就是Marshmallow在ORM中用的比较多的dump与load操作。dumploadMarshmallow提供了两个主要的方法:dump和load。dump:将Python对象转换为JSON、XML等格式。它将接受一个Python对象作为输入,并返回一个字符串或字节流,表示该对象......
  • Vue3-Composition-API-学习笔记
    01.Setup函数的体验App.vue<template><div><h2>当前计数:{{counter}}</h2><button@click="increment">+1</button><button@click="decrement">-1</button></div></template&g......
  • Vue3的手脚架使用和组件父子间通信-插槽(Options API)学习笔记
    VueCLI安装和使用全局安装最新vue3npminstall@vue/cli-g升级VueCLI:如果是比较旧的版本,可以通过下面命令来升级npmupdate@vue/cli-g通过脚手架创建项目vuecreate01_product_demoVue3父子组件的通信父传子父组件<template><div><divclass="item"v-for="(item,in......
  • 12 5阅读笔记
    《刻意练习》阅读笔记:第二部分:大脑的适应能力 大脑的结构和功能并不是固定不变的,通过刻意的练习,便刻意改变我们大脑的运作方式。 1、要改变大脑适应能力,首先我们需要先走出舒适区。走出舒适区,切忌走得太多,在距离舒适区不远的“甜蜜点”上停留,才能够长期的走在舒适区外围。......
  • [机器学习复习笔记] KNN(k近邻)
    KNN1.KNN算法(\(k\)近邻)\(k\)近邻学习(\(\text{k-nearest}\;\text{neighbor},\;k\text{-NN}\))是一种常用的监督学习方法,思路非常简单:给定一个样本数据集,对于每个输入的测试样本,在训练集中找到与该测试样本最近的\(k\)个训练样本,然后基于这\(k\)个样本的类别标......