闲着没事写篇题解

传送门

LCT维护子树的模板题

树链剖分中,子树可以用dfs序维护。但LCT你总不可能动态维护dfs序啊

LCT之所以不能直接维护子树,是因为LCT只能维护它的重儿子。我们把这棵子树称为重子树。

对于其他子树,我们称为轻子树。轻子树只会储存父节点,要不试试在跑fa的时候顺便维护轻子树?

以此题为例,设s[i]为整棵子树的大小,si[i]为虚子树大小

这里的虚子树指所有虚边连向它的儿子的大小(即s)的和

不难看出,我们询问x,y时

实际上是求(si[x]+1)(si[y]+1)

如何维护s和si?

我们发现,只有当改变了树的形态的时候,才会对s和si产生影响

access:会改变。直接在接头的时候顺便改一下

	void access(int x)
{
for (int y=0;x;y=x,x=fa[x])
{
splay(x);
si[x]+=s[ch[x][1]];
si[x]-=s[ch[x][1]=y];
pushup(x);
}
}

makeroot:虽然改了,其实只是改了下顺序,access和splay里面会改

split:没有,下一个

link和cut:link把父亲的si加一下,cut把父亲的s和si都减一下

(实际上就是直接调用了fa或ch的函数)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#define MAXN 100005
using namespace std;
namespace Splay
{
int ch[MAXN][2],fa[MAXN];
int rv[MAXN];
int si[MAXN],s[MAXN];
void pushup(int x)
{
s[x]=s[ch[x][0]]+s[ch[x][1]]+si[x]+1;
}
void pushr(int x)
{
swap(ch[x][0],ch[x][1]);
rv[x]^=1;
}
void pushdown(int x)
{
if (rv[x])
{
if (ch[x][0]) pushr(ch[x][0]);
if (ch[x][1]) pushr(ch[x][1]);
rv[x]=0;
}
}
bool isroot(int x)
{
return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
bool get(int x)
{
return ch[fa[x]][1]==x;
}
void rotate(int x)
{
int y=fa[x],z=fa[y];
int l=get(x),r=l^1;
int w=ch[x][r];
if (!isroot(y))
ch[z][get(y)]=x;
ch[x][r]=y;
ch[y][l]=w;
if (w)
fa[w]=y;
fa[y]=x;
fa[x]=z;
pushup(y);
pushup(x);
}
int q[MAXN],top;
void splay(int x)
{
q[top=1]=x;
for (int i=x;!isroot(i);i=fa[i])
q[++top]=fa[i];
for (int i=top;i>=1;i--)
pushdown(q[i]);
while (!isroot(x))
{
int y=fa[x];
if (!isroot(y))
{
if (get(x)==get(y))
rotate(y);
else
rotate(x);
}
rotate(x);
}
pushup(x);
}
}
using namespace Splay;
namespace LCT
{
void access(int x)
{
for (int y=0;x;y=x,x=fa[x])
{
splay(x);
si[x]+=s[ch[x][1]];
si[x]-=s[ch[x][1]=y];
pushup(x);
}
}
void evert(int x)
{
access(x);
splay(x);
pushr(x);
}
void split(int x,int y)
{
evert(x);
access(y);
splay(y);
}
void link(int x,int y)
{
split(x,y);
si[fa[x]=y]+=s[x];
pushup(y);
}
}
using namespace LCT;
inline int read()
{
int ans=0;
char c=getchar();
while (!isdigit(c))
c=getchar();
while (isdigit(c))
ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline char getalpha()
{
char c=getchar();
while (!isalpha(c))
c=getchar();
return c;
}
int main()
{
int n,q;
n=read(),q=read();
for (int i=1;i<=n;i++)
s[i]=1;
while (q--)
{
char c=getalpha();
int x,y;
x=read(),y=read();
if (c=='A')
link(x,y);
else
{
split(x,y);
printf("%I64d\n",(long long)(si[x]+1)*(si[y]+1));
}
}
return 0;
}

【BJOI2014】大融合【LCT】的更多相关文章

  1. [BZOJ4530][Bjoi2014]大融合 LCT + 启发式合并

    [BZOJ4530][Bjoi2014]大融合 试题描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是 ...

  2. 【bzoj4530】[Bjoi2014]大融合 LCT维护子树信息

    题目描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够联通的树上路过它的简单路径的数量 ...

  3. Luogu4219 BJOI2014 大融合 LCT

    传送门 题意:写一个数据结构,支持图上连边(保证图是森林)和询问一条边两端的连通块大小的乘积.$\text{点数.询问数} \leq 10^5$ 图上连边,$LCT$跑不掉 支持子树$size$有点麻 ...

  4. BZOJ4530[Bjoi2014]大融合——LCT维护子树信息

    题目描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它的简单路径的数 ...

  5. BZOJ.4530.[BJOI2014]大融合(LCT)

    题目链接 BZOJ 洛谷 详见这 很明显题目是要求去掉一条边后两边子树sz[]的乘积. LCT维护的是链的信息,那么子树呢? 我们用s_i[x]来记录轻边连向x的子树的和(记作虚儿子),那么sum[x ...

  6. [BJOI2014]大融合(LCT)

    题面 luogu bzoj是权限题.. 题解 \(LCT\)维护子树信息 因为\(LCT\)中有一些虚子树,\(splay\)维护不了. 所以要新开一个数组来记录 然后注意\(link\)时 是先\( ...

  7. 【洛谷 P4219】 [BJOI2014]大融合(LCT)

    题目链接 维护子树信息向来不是\(LCT\)所擅长的,所以我没搞懂qwq 权当背背模板吧.Flash巨佬的blog里面写了虽然我没看懂. #include <cstdio> #define ...

  8. bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...

  9. BZOJ4530:[BJOI2014]大融合(LCT)

    Description 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它 ...

  10. P4219 [BJOI2014]大融合 LCT维护子树大小

    \(\color{#0066ff}{ 题目描述 }\) 小强要在\(N\)个孤立的星球上建立起一套通信系统.这套通信系统就是连接\(N\)个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一 ...

随机推荐

  1. java学习笔记记录

    Java内存模型: Java虚拟机规范中将Java运行时数据分为六种. 1.程序计数器:是一个数据结构,用于保存当前正常执行的程序的内存地址.Java虚拟机的多线程就是通过线程轮流切换并分配处理器时间 ...

  2. 如何阻止自动更新‘updated_at’和'created_at'

    可以在模版中添加一条代码: public $timestamps = false;

  3. NYOJ 1022 合纵连横 (并查集)

    题目链接 描述 乱世天下,诸侯割据.每个诸侯王都有一片自己的领土.但是不是所有的诸侯王都是安分守己的,实力强大的诸侯国会设法吞并那些实力弱的,让自己的领土面积不断扩大.而实力弱的诸侯王为了不让自己的领 ...

  4. bzoj 1934最小割

    比较显然的最小割的题,增加节点source,sink,对于所有选1的人我们可以(source,i,1),选0的人我们可以(i,sink,1),然后对于好朋友我们可以连接(i,j,1)(j,i,1),然 ...

  5. python开发规范(转载)

    转载自http://www.cnblogs.com/wangcp-2014/p/4838952.html 目录 代码布局 1.1 缩进 1.2 表达式和语句中的空格 1.3 行的最大长度 1.4 空行 ...

  6. Oracle-AWR报告简介及如何生成【转】

    AWR报告 awr报告是oracle 10g及以上版本提供的一种性能收集和分析工具,它能提供一个时间段内整个系统资源使用情况的报告,通过这个报告,我们就可以了解Oracle数据库的整个运行情况,比如硬 ...

  7. python操作adb代码

    adb命令的练习 #!/usr/bin/env python # encoding: utf-8 import os import re nameplt=re.compile("packag ...

  8. android sdcard 权限管理策略研究

    自从android4.4 以来,第三方应用程序是不能再随便的访问sdcard了,从开发者的角度而言,研究一下android系统到底是怎么样来实现这样的控制还是比较有价值的. 首先分析下现状,现在已知, ...

  9. github--403错误

    错误信息如下: $ git push origin master error: The requested URL returned error: while accessing https://gi ...

  10. SyntaxError: Missing parentheses in call to 'print' 这个错误原因是Python版本问题

    问题 print "www.baidu.com"           Python2 print ("www.baidu.com")     Python3 出 ...