洛谷 P4219 [BJOI2014]大融合【LCT】
时间:2020-04-17
本文章向大家介绍洛谷 P4219 [BJOI2014]大融合【LCT】,主要包括洛谷 P4219 [BJOI2014]大融合【LCT】使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
传送门
LCT 维护子树信息,对于每个节点,另开一个变量 \(f_2\) 记录其虚子树的总和,那么它的子树和就是 \(f[u]=f[ls]+f[rs]+val[u]+f_2[u]\)。
这个维护操作就比较讲究了,在原树的形态发生变化的时候一定要注意即时修改 \(f_2\):
\(access\):将实边与虚边互换,那么 \(f_2[u]=f_2[u]-f[t]+f[rs]\)。
\(link\):为一个点 \(y\) 增加虚子树 \(x\) ,所以 \(f_2[y]+=f[x]\)。
其他操作均不需要单独的改值,因为并没有修改树的形态,\(cut\) 虽然改了树的形态但是也可以通过 pushup 自己更新到正确的值。
- 注意对节点的值进行更改的时候一定要先将它转到 splay 的根,这样它现在的值才是正确的值,切记切记。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct LinkCutTree{
#define ls(x) (ch[x][0])
#define rs(x) (ch[x][1])
int fa[N],ch[N][2],siz[N],rev[N],siz2[N];
int ident(int p,int f){return ch[f][1]==p;}
void connect(int p,int f,int k){ch[f][k]=p;fa[p]=f;}
bool ntroot(int p){return ls(fa[p])==p||rs(fa[p])==p;}
void pushup(int p){siz[p]=siz[ls(p)]+siz[rs(p)]+1+siz2[p];}
void Rev(int p){swap(ls(p),rs(p));rev[p]^=1;}
void pushdw(int p){if(rev[p]) Rev(ls(p)),Rev(rs(p));rev[p]=0;}
void rotate(int p){
int f=fa[p],ff=fa[f],k=ident(p,f);
connect(ch[p][k^1],f,k);
fa[p]=ff;
if(ntroot(f)) ch[ff][ident(f,ff)]=p;
connect(f,p,k^1);
pushup(f),pushup(p);
}
void pushall(int p){if(ntroot(p))pushall(fa[p]);pushdw(p);}
void splay(int p){
pushall(p);
while(ntroot(p)){
int f=fa[p],ff=fa[f];
if(ntroot(f)) ident(p,f)^ident(f,ff)?rotate(p):rotate(f);
rotate(p);
}
}
void access(int p){for(int t=0;p;p=fa[t=p])splay(p),siz2[p]+=siz[rs(p)]-siz[t],rs(p)=t,pushup(p);}
void makert(int p){access(p);splay(p);Rev(p);}
int findrt(int p){access(p);splay(p);while(ls(p))p=ls(p),pushdw(p);splay(p);return p;}
void split(int p,int q){makert(p);access(q);splay(q);}
void link(int p,int q){makert(p);makert(q);fa[p]=q;siz2[q]+=siz[p];pushup(q);}
void cut(int p,int q){split(p,q);if(ls(q)==p&&!rs(p)) fa[p]=ls(q)=0;pushup(p);pushup(q);}
int getsize(int p){makert(p);return siz[p];}
}lct;
int n,q;
int main(){
scanf("%d%d",&n,&q);
while(q--){
char opt[5];int x,y;
scanf("%s%d%d",opt,&x,&y);
if(opt[0]=='A') lct.link(x,y);
else{
lct.cut(x,y);
int siz1=lct.getsize(x),siz2=lct.getsize(y);
printf("%lld\n",1ll*siz1*siz2);
lct.link(x,y);
}
}
return 0;
}
原文地址:https://www.cnblogs.com/BakaCirno/p/12717550.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 数据库能力测试:SQL 语句改错
- IDEA 导入并运行 Eclipse 的 JavaWeb 项目
- 使用思科模拟器 Cisco Packet Tracer 模拟交换机基本配置
- IDEA 连接 SQL Sever
- Ms SQL Server 如何导入数据库
- 移动直播连麦PK快速调试
- Python:使用爬虫获取中国最好的大学排名数据(爬虫入门)
- Python:酒鬼漫步
- apache-commons-dbutils + Druid + JDBC 简单实现 CRUD
- Python:将一个 csv 文件转为 json 文件存储到磁盘
- TKE上搭建集群Dashboard
- FFmpeg+OpenSLES 实现音频播放
- 使用 JSP+Servlet 模仿京东页面实现购物车功能
- Python 绘制科赫雪花的简单实现
- IP 数据报格式详解