BZOJ.4530.[BJOI2014]大融合(LCT)
很明显题目是要求去掉一条边后两边子树sz[]的乘积。
LCT维护的是链的信息,那么子树呢?
我们用s_i[x]来记录轻边连向x的子树的和(记作虚儿子),那么sum[x]更新时就是sum[lson]+sum[rson]+val[x]+s_i[x]。
现在需要s_i[x],考虑什么时候会影响它。
Splay()影响的只是节点在辅助树Splay中的相对位置,并不会对树中的信息产生影响。
Access()需要更改右儿子,即加上一个虚儿子加上一个实儿子,对应更新即可,如果只需要维护sum之类不需要Update()(一加一减)。
Make_root()无影响。虽然使整棵树形态都发生了变化,但这一操作并不直接用来获取信息。
Split()不需要考虑(仅是调用函数)。
Find_root()无影响。
Link()后y多了一个虚儿子,那么sum[y],s_i[y]加上x。这一步之前要将y旋到根(Access(y),Splay(y)),否则y以上的部分不会更新。
Cut()无影响。虽然少了个儿子,但这一操作不会用来直接获取信息,下次获取信息时会更新,不会影响正确性。
这样答案就是x,y两边s_i+1的乘积(分离出路径后实的就是x->y了,再加上自己),或是(y为根时)sz[x]*(sz[y]-sz[x])
//3264kb 1380ms
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=1e5+5;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
namespace LCT
{
#define lson son[x][0]
#define rson son[x][1]
int fa[N],son[N][2],sz[N],sz_i[N],sk[N];
bool tag[N];
inline void Update(int x){
sz[x]=sz[lson]+sz[rson]+1+sz_i[x];
}
inline bool n_root(int x){
return son[fa[x]][0]==x||son[fa[x]][1]==x;
}
inline void Rev(int x){
std::swap(lson,rson), tag[x]^=1;
}
inline void PushDown(int x){
if(tag[x]) Rev(lson),Rev(rson),tag[x]=0;
}
void Rotate(int x)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(n_root(a)) son[b][son[b][1]==a]=x;
if(son[x][r]) fa[son[x][r]]=a;
fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a;
Update(a);
}
void Splay(int x)
{
int t=1,a=x,b; sk[1]=x;//
while(n_root(a)) sk[++t]=a=fa[a];
while(t) PushDown(sk[t--]);
while(n_root(x))
{
a=fa[x], b=fa[a];
if(n_root(a)) Rotate(son[a][1]==x^son[b][1]==a?x:a);
Rotate(x);
}
Update(x);
}
void Access(int x){
for(int pre=0; x; x=fa[pre=x])
{
Splay(x);
sz_i[x]+=sz[rson], sz_i[x]-=sz[rson=pre];
// Update(x);
}
}
void Make_root(int x){
Access(x), Splay(x), Rev(x);
}
void Split(int x,int y){
Make_root(x), Access(y), Splay(y);
}
void Link(int x,int y){
Split(x,y), sz_i[fa[x]=y]+=sz[x], Update(y);//更新!
}
long long Query(int x,int y){
Split(x,y); return 1ll*(sz_i[x]+1)*(sz_i[y]+1);//1ll*sz[x]*(sz[y]-sz[x]);
}
}
int main()
{
int n=read(),q=read(),x,y; char opt[3];
for(int i=1; i<=n; ++i) LCT::sz[i]=1;
while(q--)
{
scanf("%s",opt),x=read(),y=read();
if(opt[0]=='A') LCT::Link(x,y);
else printf("%lld\n",LCT::Query(x,y));
}
return 0;
}
BZOJ.4530.[BJOI2014]大融合(LCT)的更多相关文章
- bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...
- BZOJ:4530: [Bjoi2014]大融合
4530: [Bjoi2014]大融合 拿这题作为lct子树查询的练手.本来以为这会是一个大知识点,结果好像只是一个小技巧? 多维护一个虚边连接着的子树大小即可. #include<cstdio ...
- bzoj 4530: [Bjoi2014]大融合【LCT】
新姿势,一般来讲LCT只能维护splay重边里的数据,而这里要求维护整颗子树的size 多维护一个sq表示当前点轻儿子的size和,si表示包括轻重边的整颗子树的大小 然后需要改sq的地方是link和 ...
- 【刷题】BZOJ 4530 [Bjoi2014]大融合
Description 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它 ...
- [BZOJ4530][Bjoi2014]大融合 LCT + 启发式合并
[BZOJ4530][Bjoi2014]大融合 试题描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是 ...
- [BJOI2014]大融合(LCT)
题面 luogu bzoj是权限题.. 题解 \(LCT\)维护子树信息 因为\(LCT\)中有一些虚子树,\(splay\)维护不了. 所以要新开一个数组来记录 然后注意\(link\)时 是先\( ...
- 【BZOJ】4530: [Bjoi2014]大融合
[题意]给定n个点的树,从无到有加边,过程中动态询问当前图某条边两端连通点数的乘积,n<=10^5. [算法]线段树合并+并查集 (||LCT(LCT维护子树信息 LCT维护子树信息(+启发式合 ...
- 【bzoj4530】[Bjoi2014]大融合 LCT维护子树信息
题目描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够联通的树上路过它的简单路径的数量 ...
- Luogu4219 BJOI2014 大融合 LCT
传送门 题意:写一个数据结构,支持图上连边(保证图是森林)和询问一条边两端的连通块大小的乘积.$\text{点数.询问数} \leq 10^5$ 图上连边,$LCT$跑不掉 支持子树$size$有点麻 ...
随机推荐
- MySQL基于LVM快照的备份恢复(临时)
目录1.数据库全备份2.准备LVM卷3.数据恢复到LVM卷4.基于LVM快照备份数据5.数据灾难恢复6.总结 写在前面:测试环境中已安装有mysql 5.5.36数据库,但数据目录没有存放在LVM卷, ...
- linux windows 共享文件夹
1.首先在windows上共享一个目录,如:共享了目录share,用户和密码都是:massky 2.在linux机器上,在/mnt目录下建立一个ml45目录,使用root用户,执行下面命令: moun ...
- zabbix系列(六)zabbix添加对ubuntu系统的监控
在ubuntu os上安装agent,使用如下命令: wget http://mirrors.aliyun.com/zabbix/zabbix/3.0/ubuntu/pool/main/z/zabbi ...
- mysql的日志及利用mysqldump备份及还原
日志文件:6类 一般查询日志:log,general_log,log_output 慢查询日志: 错误日志 二进制日志 中继日志 ...
- PHP导出CVS格式文件
$csvContent="csvzero,csvone,csvtwo,csvthree,csvfour,csvfive"; header("Content-Type: a ...
- ssh-keygen -t rsa -b 4096 -C "邮箱"
ssh-keygen -t rsa -b 4096 -C "邮箱":这条命令的目的是为了让本地机器ssh登录远程机器上的GitHub账户无需输入密码.将这条命令分解: 1.ssh- ...
- 【【C++ Primer 第15章】 虚析构函数
学习资料 • C++中基类的析构函数为什么要用virtual虚析构函数 虚析构函数 1. 正文 直接的讲,C++中基类采用virtual虚析构函数是为了防止内存泄漏.具体地说,如果派生类中申请了内存空 ...
- IntelliJ IDEA设置不自动打开最后关闭的项目
- JDK的get请求方式
package com.example.wang.testapp3; import android.app.ProgressDialog; import android.os.Bundle; impo ...
- Spring框架+Struts2框架第一次整合
1:Spring框架和Struts2框架如何整合??? Spring 负责对象创建 Struts2 用Action处理请求 2:Spring与Struts2框架整合的关键点: 让struts2框架ac ...