QWQ

这个题目是LCT维护子树信息的经典应用

根据题目信息来看,对于一个这条边的两个端点各自的\(size\)乘起来,不过这个应该算呢?

我们可以考虑在LCT上多维护一个\(xv[i]\)表示\(i\)的虚子树的子树和,然后维护\(sum[i]\)表示\(i\)的虚+实子树之和。

那么对于一个点\(x\),他在原树上的字数大小就应该是$$size = xv[x]+sum[ch[x][1]]+1$$

这是个经典套路!

对于这个题来说,我们可以通过\(split(x,y)\),然后\(ans\)就等于\((xv[x]+1)\times (xv[y]+1)\)

这个地方可以理解为,x的虚儿子是以x为根,不经过\((x,y)\)这条边的 所有子树和,正好符合题目要求,y也是同理。

当然,也存在别的计算方法:我们\(makeroot(y)\),然后直接用x的子树大小,乘上y的子树大小减去x的。也是可以的。道理和上面的类似

直接上代码

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
#include<set> using namespace std; inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
} const int maxn = 2e5+1e2; int size[maxn];
int xv[maxn];
int ch[maxn][3];
int fa[maxn];
int n,m,cnt;
int st[maxn];
int rev[maxn]; int son(int x)
{
if (ch[fa[x]][0]==x) return 0;
else return 1;
} bool notroot(int x)
{
return ch[fa[x]][0]==x || ch[fa[x]][1]==x;
} void update(int x)
{
size[x]=size[ch[x][0]]+size[ch[x][1]]+xv[x]+1;
} void reverse(int x)
{
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
} void pushdown(int x)
{
if (rev[x])
{
if (ch[x][0]) reverse(ch[x][0]);
if (ch[x][1]) reverse(ch[x][1]);
rev[x]=0;
}
} void rotate(int x)
{
int y=fa[x],z=fa[y];
int b=son(x),c=son(y);
if (notroot(y)) ch[z][c]=x;
fa[x]=z;
ch[y][b]=ch[x][!b];
fa[ch[x][!b]]=y;
ch[x][!b]=y;
fa[y]=x;
update(y);
update(x);
} void splay(int x)
{
int y=x,cnt=0;
st[++cnt]=y;
while (notroot(y)) y=fa[y],st[++cnt]=y;
while (cnt) pushdown(st[cnt--]);
while (notroot(x))
{
int y=fa[x],z=fa[y];
int b=son(x),c=son(y);
if (notroot(y))
{
if (b==c) rotate(y);
else rotate(x);
}
rotate(x);
}
update(x);
} void access(int x)
{
for (int y=0;x;y=x,x=fa[x])
{
splay(x);
xv[x]+=size[ch[x][1]];
ch[x][1]=y;
xv[x]-=size[y];
}
} void makeroot(int x)
{
access(x);
splay(x);
reverse(x);
} int findroot(int x)
{
access(x);
splay(x);
while (ch[x][0])
{
pushdown(x);
x=ch[x][0];
}
return x;
} void split(int x,int y)
{
makeroot(x);
access(y);
splay(y);
} void link(int x,int y)
{
split(x,y);
if (findroot(y)!=x)
{
fa[x]=y;
xv[y]+=size[x];
}
update(y);
} int q; int main()
{
n=read(),q=read();
for (int i=1;i<=q;i++)
{
char s[10];
scanf("%s",s+1);
if (s[1]=='A')
{
int x=read(),y=read();
link(x,y);
}
else
{
int x=read(),y=read();
split(x,y);
printf("%lld\n",1ll*(xv[x]+1)*(xv[y]+1));
}
}
return 0;
}

洛谷4219 BJOI2014大融合(LCT维护子树信息)的更多相关文章

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

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

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

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

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

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

  4. [BJOI2014]大融合 LCT维护子树信息

    Code: #include <cstdio> #include <algorithm> #include <cstring> #include <strin ...

  5. Loj 2230. 「BJOI2014」大融合 (LCT 维护子树信息)

    链接:https://loj.ac/problem/2230 思路: 设立siz数组保存虚点信息,sum表示总信息 维护子树信息link操作和access操作需要进行一些改动 可参考博客:https: ...

  6. bzoj 4530 大融合 —— LCT维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 用LCT维护子树 size,就是实边和虚边分开维护: 看博客:https://blog ...

  7. 大融合——LCT维护子树信息

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

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

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

  9. 洛谷P4219 [BJOI2014]大融合(LCT,Splay)

    LCT维护子树信息的思路总结与其它问题详见我的LCT总结 思路分析 动态连边,LCT题目跑不了了.然而这题又有点奇特的地方. 我们分析一下,查询操作就是要让我们求出砍断这条边后,x和y各自子树大小的乘 ...

随机推荐

  1. MySQL日志系统bin log、redo log和undo log

    MySQL日志系统bin log.redo log和undo log   今人不见古时月,今月曾经照古人. 简介:日志是MySQL数据库的重要组成部分,记录着数据库运行期间各种状态信息,主要包括错误日 ...

  2. 速查列表:Apache SkyWalking OAL 的 域(Scopes)

    OAL简介 在流模式(Streaming mode)下,SkyWalking 提供了 观测分析语言(Observability Analysis Language,OAL) 来分析流入的数据. OAL ...

  3. 整理之Service

    Service 基础 一个Service的基本结构 class MyService : Service() { private val mBinder = MyBinder() override fu ...

  4. Qt 自定义事件

    Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...

  5. Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用

    原文地址: Jetpack Compose学习(3)--图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝 本篇分别对常用的组件:图标(Ic ...

  6. 启动线程组报错:Error occurred starting thread group :test_1, error message:Invalid duration 0 set in Thread Group:test_1, see log file for more details

    线程组基础信息都已经配置好,启动时报错,如下图: 排查原因:勾选了线程组调度器,并未设置参数 解决方案:取消勾选或者设置参数

  7. Tricks

    由于本人着实有些菜,因此在此积累一些巧妙的 \(Tricks\) ,以备不时之需... 与其说是 \(Tricks\) 不如说是学习笔记?? 数学 组合数 常见的数列 斐波那契数列 图论 树论 \(P ...

  8. MongoDB(14)- 查询 null 字段或缺少某个字段的文档

    插入测试数据 db.inventory.insertMany([ { _id: 1, item: null }, { _id: 2 } ]) 后面的栗子都会用到这里的测试数据 查询匹配包含值为 nul ...

  9. jvm学习笔记:类加载过程

    类加载器子系统 类加载器的作用是加载class文件到内存 加载阶段->链接阶段->初始化阶段 ClassLoader只负责class文件的加载,至于是否能够运行由执行引擎判断 加载的类信息 ...

  10. Java跨平台原理(字节码文件,虚拟机)

    介绍 C/C++语言都直接编译成针对特定平台机器码.如果要跨平台,需要使用相应的编译器重新编译. Java源程序(.java)要先编译成与平台无关的字节码文件(.class),然后字节码文件再解释成机 ...