这一篇重点探讨LCT的应用

例:bzoj 2631 tree2(国家集训队)

LCT模板操作之一,利用SPLAY可以进行区间操作这一性质对维护懒惰标记,注意标记下传顺序和如何下传

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define uint unsigned int
#define mode 51061
using namespace std;
uint c[100005][2];
uint v[100005];
uint s[100005];
uint alazy[100005];
uint mlazy[100005];
uint f[100005];
uint ttag[100005];
uint huge[100005];
uint n,m;
char ss[5];
bool berot(uint rt)
{
if(c[f[rt]][0]==rt||c[f[rt]][1]==rt)
{
return 0;
}
return 1;
}
void reverse(uint rt)
{
swap(c[rt][0],c[rt][1]);
ttag[rt]^=1;
}
void update(uint rt)
{
huge[rt]=huge[c[rt][0]]+huge[c[rt][1]]+1;
s[rt]=(s[c[rt][0]]+s[c[rt][1]]+v[rt])%mode;
}
void mul(uint rt,uint val)
{
s[rt]*=val;
s[rt]%=mode;
v[rt]*=val;
v[rt]%=mode;
alazy[rt]*=val;
alazy[rt]%=mode;
mlazy[rt]*=val;
mlazy[rt]%=mode;
}
void add(uint rt,uint val)
{
s[rt]+=val*huge[rt];
s[rt]%=mode;
alazy[rt]+=val;
alazy[rt]%=mode;
v[rt]+=val;
v[rt]%=mode;
}
void pushdown(uint rt)
{
if(mlazy[rt]!=1)
{
mul(c[rt][0],mlazy[rt]);
mul(c[rt][1],mlazy[rt]);
mlazy[rt]=1;
}
if(alazy[rt])
{
add(c[rt][0],alazy[rt]);
add(c[rt][1],alazy[rt]);
alazy[rt]=0;
}
if(ttag[rt])
{
if(c[rt][0])
{
reverse(c[rt][0]);
}
if(c[rt][1])
{
reverse(c[rt][1]);
}
ttag[rt]=0;
}
}
void repush(uint rt)
{
if(!berot(rt))
{
repush(f[rt]);
}
pushdown(rt);
}
void rotate(uint rt)
{
uint ltyp=0;
uint fa=f[rt];
uint ffa=f[fa];
if(c[fa][1]==rt)
{
ltyp=1;
}
if(!berot(fa))
{
if(c[ffa][0]==fa)
{
c[ffa][0]=rt;
}else
{
c[ffa][1]=rt;
}
}
c[fa][ltyp]=c[rt][ltyp^1];
c[rt][ltyp^1]=fa;
f[c[fa][ltyp]]=fa;
f[fa]=rt;
f[rt]=ffa;
update(fa);
}
void splay(uint rt)
{
repush(rt);
while(!berot(rt))
{
uint fa=f[rt];
uint ffa=f[fa];
if(!berot(fa))
{
if((c[fa][0]==rt&&c[ffa][0]!=fa)||(c[fa][1]==rt&&c[ffa][1]!=fa))
{
rotate(rt);
}else
{
rotate(fa);
}
}
rotate(rt);
}
update(rt);
}
void access(uint rt)
{
uint y=0;
while(rt)
{
splay(rt);
c[rt][1]=y;
update(rt);
y=rt;
rt=f[rt];
}
}
void makeroot(uint rt)
{
access(rt);
splay(rt);
reverse(rt);
}
void split(uint st,uint ed)
{
makeroot(st);
access(ed);
splay(ed);
}
void link(uint st,uint ed)
{
makeroot(st);
f[st]=ed;
}
void cut(uint st,uint ed)
{
split(st,ed);
f[st]=c[ed][0]=0;
}
inline uint read()
{
uint f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f =1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
n=read(),m=read();
for(uint i=1;i<=n;i++)
{
huge[i]=1;
v[i]=1;
mlazy[i]=1;
}
for(uint i=1;i<n;i++)
{
uint x=read(),y=read();
link(x,y);
}
while(m--)
{
scanf("%s",ss);
if(ss[0]=='+')
{
uint x=read(),y=read(),z=read();
split(x,y);
add(y,z);
}else if(ss[0]=='-')
{
uint x=read(),y=read(),z=read(),q=read();
cut(x,y);
link(z,q);
}else if(ss[0]=='*')
{
uint x=read(),y=read(),z=read();
split(x,y);
mul(y,z);
}else
{
uint x=read(),y=read();
split(x,y);
printf("%u\n",s[y]);
}
}
return 0;
}

例:bzoj 3282 luogu 3690 link-cut-tree 模板

模板题,用SPLAY维护即可

注意判断加边的合法性

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
using namespace std;
int c[400005][2];
ll s[400005];
int f[400005];
bool ttag[400005];
int v[400005];
int n,m;
bool berot(int rt)
{
if(c[f[rt]][0]==rt||c[f[rt]][1]==rt)
{
return 0;
}
return 1;
}
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void update(int rt)
{
s[rt]=(ll)s[c[rt][0]]^(ll)s[c[rt][1]]^(ll)v[rt];
}
void reverse(int rt)
{
swap(c[rt][0],c[rt][1]);
ttag[rt]^=1;
}
void pushdown(int rt)
{
if(ttag[rt])
{
if(c[rt][0])reverse(c[rt][0]);
if(c[rt][1])reverse(c[rt][1]);
ttag[rt]=0;
}
}
void repush(int rt)
{
if(!berot(rt))
{
repush(f[rt]);
}
pushdown(rt);
}
void rotate(int rt)
{
int ltyp=0;
int fa=f[rt];
int ffa=f[fa];
if(c[fa][1]==rt)
{
ltyp=1;
}
if(!berot(fa))
{
if(c[ffa][1]==fa)
{
c[ffa][1]=rt;
}else
{
c[ffa][0]=rt;
}
}
c[fa][ltyp]=c[rt][ltyp^1];
c[rt][ltyp^1]=fa;
f[c[fa][ltyp]]=fa;
f[fa]=rt;
f[rt]=ffa;
update(fa);
}
void splay(int rt)
{
repush(rt);
while(!berot(rt))
{
int fa=f[rt];
int ffa=f[fa];
if(!berot(fa))
{
if((c[fa][0]==rt&&c[ffa][0]!=fa)||(c[fa][1]==rt&&c[ffa][1]!=fa))
{
rotate(rt);
}else
{
rotate(fa);
}
}
rotate(rt);
}
update(rt);
}
void access(int rt)
{
int y=0;
while(rt)
{
splay(rt);
c[rt][1]=y;
update(rt);
y=rt;
rt=f[rt];
}
}
void makeroot(int rt)
{
access(rt);
splay(rt);
reverse(rt);
}
int getroot(int rt)
{
access(rt);
splay(rt);
while(c[rt][0])
{
pushdown(rt);
rt=c[rt][0];
}
return rt;
}
void link(int st,int ed)
{
makeroot(st);
if(getroot(ed)==st)
{
return;
}
f[st]=ed;
}
void cut(int st,int ed)
{
makeroot(ed);
if(getroot(st)==ed&&f[ed]==st&&!c[ed][1])
{
c[st][0]=f[ed]=0;
update(st);
}
}
void split(int st,int ed)
{
makeroot(st);
access(ed);
splay(ed);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
{
v[i]=read();
}
while(m--)
{
int typ=read(),x=read(),y=read();
if(typ==0)
{
split(x,y);
printf("%lld\n",s[y]);
}else if(typ==1)
{
link(x,y);
}else if(typ==2)
{
cut(x,y);
}else
{
splay(x);
v[x]=y;
}
}
return 0;
}

在上面两个模板应用中,有一个要点:repush!

在传递翻转标记时,我们要注意一定从上向下传标记!

SPLAY,LCT学习笔记(五)的更多相关文章

  1. LCT 学习笔记

    LCT学习笔记 前言 自己定的学习计划看起来完不成了(两天没学东西,全在补题),决定赶快学点东西 于是就学LCT了 简介 Link/Cut Tree是一种数据结构,我们用它解决动态树问题 但是LCT不 ...

  2. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  3. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  4. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  5. Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  6. Typescript 学习笔记五:类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  7. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  8. muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor

    目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...

  9. python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍

    python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ...

  10. Go语言学习笔记五: 条件语句

    Go语言学习笔记五: 条件语句 if语句 if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } 竟然没有括号,和python很像.但是有大括号,与python又不一样. 例子: pa ...

随机推荐

  1. Nginx核心配置文件常用参数详解

    Nginx核心配置文件常用参数详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于Nginx权威文档的话童鞋们可以参考Nginx官方文档介绍:http://nginx.org/ ...

  2. buildroot构建项目(八)--- u-boot 2017.11 适配开发板修改 5 ---- 系统启动初始化之五

    执行完 board_init_f 后,跳回到 crt0.S中继续执行汇编语言 ldr r0, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp, ...

  3. Maven私服

    1.关于中央仓库注意事项地址: 目前来说: http://repo1.maven.org/maven2/是真正的 Maven 中央仓库的地址,该地址内置在Maven 的源码中,其他的都是镜像.索引: ...

  4. Python3 configparse模块(配置)

    ConfigParser模块在python中是用来读取配置文件,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节(section),每个节可以有多个参数(键=值). 注意:在 ...

  5. Python startswith() 函数 判断字符串开头

    Python startswith() 函数 判断字符串开头 函数:startswith() 作用:判断字符串是否以指定字符或子字符串开头 一.函数说明语法:string.startswith(str ...

  6. camera驱动框架分析(上)【转】

    转自:https://www.cnblogs.com/rongpmcu/p/7662738.html 前言 camera驱动框架涉及到的知识点比较多,特别是camera本身的接口就有很多,有些是直接连 ...

  7. Git相关二三事(git reflog 和彩色branch)【转】

    转自:https://www.jianshu.com/p/3622ed542c3b 背景 git太常用了,虽然,用起来不难,但也有很多小技巧的东西... 1. 后悔药 哪天不小心,写完代码,没comm ...

  8. 【转】htop使用详解--史上最强(没有之一)

    在管理进程时通常要借助一些工具,比较常用的就是ps和top了:不过CentOS还为我们提供了一个更加强大的工具htop,下面就来了解一下此工具的使用方法.一.安装htop htop工具在epel源中提 ...

  9. mysql系列九、mysql语句执行过程及运行原理(分组查询和关联查询原理)

    一.背景介绍 了解一个sql语句的执行过程,了解一部分都做了什么,更有利于对sql进行优化,因为你知道它的每一个连接.where.分组.子查询是怎么运行的,都干了什么,才会知道怎么写是不合理的. 大致 ...

  10. HTML学习笔记09-列表

    HTML支持无序,有序,自定义列表 列表项内部可以使用段落.换行符.图片.连接.以及其他列表等 无序列表 无序列表使用粗体圆点(典型的小黑圆圈)进行标记,列表始于<ul>标签,列表项使用& ...