大融合 bzoj-4530 Bjoi-2014

题目大意:n个点,m个操作,支持:两点连边;查询两点负载:负载。边(x,y)的负载就是将(x,y)这条边断掉后能和x联通的点的数量乘以能和y联通的点的数量。数据保证任意时刻,点和边构成的都是森林或者树。

注释:$1\le n,m\le 10^5$。


想法:新学了一发LCT维护子树信息,更一道例题。

话说LCT维护子树信息应该怎么做?其实也非常简单。我们只需要将所有的信息都加到父节点上即可。

具体的,我们除了维护子树和sum之外另维护一个值other,表示这个节点的所有虚儿子的子树和。

然后这东西在access中将所有儿子都扔了的之后更新一下。

然后insert的时候更新一下即可。

然后维护我们用pushup维护。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ls ch[p][0]
#define rs ch[p][1]
#define get(x) (ch[f[x]][1]==x)
#define N 100010
using namespace std;
typedef long long ll;
int ch[N][2],oth[N],sum[N],f[N];
bool rev[N];
inline bool isroot(int p)
{
// puts("Fuck:isroot");
return ch[f[p]][0]!=p&&ch[f[p]][1]!=p;
}
inline void pushup(int p)
{
// puts("Fuck:pushup");
sum[p]=sum[ls]+sum[rs]+oth[p]+1;
}
inline void pushdown(int p)
{
// puts("Fuck:pushdown");
if(!rev[p]) return;
swap(ch[ls][0],ch[ls][1]); swap(ch[rs][0],ch[rs][1]);
rev[ls]^=1; rev[rs]^=1; rev[p]=0;
}
void update(int p)
{
// puts("Fuck:update");
if(!isroot(p)) update(f[p]);
pushdown(p);
}
void rotate(int x)
{
// puts("Fuck:rotate");
int y=f[x],z=f[y],k=get(x);
if(!isroot(y)) ch[z][ch[z][1]==y]=x;
ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
ch[x][!k]=y; f[y]=x; f[x]=z;
pushup(y); pushup(x);
}
void splay(int x)
{
// puts("Fuck:splay");
update(x);
for(int t;t=f[x],!isroot(x);rotate(x))
{
if(!isroot(t)) rotate(get(x)==get(t)?t:x);
}
}
void access(int p)
{
// puts("Fuck:access");
int t=0;
while(p) splay(p),oth[p]+=sum[rs]-sum[t],rs=t,pushup(p),t=p,p=f[p];
}
void makeroot(int p)
{
// puts("Fuck:makeroot");
access(p); splay(p);
swap(ls,rs); rev[p]^=1;
}
void link(int x,int y)
{
// puts("Fuck:link");
makeroot(x); makeroot(y);
f[x]=y; oth[y]+=sum[x]; pushup(y);
}
int main()
{
int n,m,x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) sum[i]=1;
char str[10];
while(m--)
{
scanf("%s%d%d",str,&x,&y);
if(str[0]=='A') link(x,y);
else makeroot(x),makeroot(y),printf("%lld\n",(ll)sum[x]*(sum[y]-sum[x]));
}
return 0;
}
/*
8 6 A 2 3 A 3 4 A 3 8 A 8 7 A 6 5 Q 3 8
*/

小结:如果没听懂可以到JCY的blog中看一看。

[bzoj4530][Bjoi2014]大融合_LCT的更多相关文章

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

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

  2. BZOJ_4530_[Bjoi2014]大融合_LCT

    BZOJ_4530_[Bjoi2014]大融合_LCT Description 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个 ...

  3. BZOJ4530 BJOI2014大融合(线段树合并+并查集+dfs序)

    易知所求的是两棵子树大小的乘积.先建出最后所得到的树,求出dfs序和子树大小.之后考虑如何在动态加边过程中维护子树大小.这个可以用树剖比较简单的实现,但还有一种更快更优美的做法就是线段树合并.对每个点 ...

  4. BZOJ4530: [Bjoi2014]大融合

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

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

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

  6. 2019.01.14 bzoj4530: [Bjoi2014]大融合(线段树合并)

    传送门 线段树合并菜题. 题意简述:nnn个点,支持连边以及查询一个点所在连通块中经过这个点的路径条数,保证这张图时刻为森林. 思路: 先建出所有操作完之后的树统计出dfsdfsdfs序 注意有可能是 ...

  7. [BZOJ4530][Bjoi2014]大融合(LCT)

    传送门 大佬们似乎都是用树剖+并查集优雅地A了此题 然后我太弱了,只能打打LCT的板子 虽然的确可以挺无脑的A掉…… 不过至少这题教了我该怎么维护LCT上虚子树的信息,具体看这里 首先,答案很明显是断 ...

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

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

  9. bzoj4530 [Bjoi2014]大融合 子树信息 LCT

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4530/ 题解 想要求出一条边的负载那么就是要求出一个点为根的时候的另一个点的子树大小. 又因为 ...

随机推荐

  1. eclipse ------validation功能

    今天来讲讲eclipse 的validation功能,该功能用于检测代码存在的“潜在”问题,比如:JSP文件的语法错误,XML中的schema错误等,这么好的功能还有什么可讲的呢,我今天要讲的是val ...

  2. npm 与 package.json 快速入门教程

    npm 与 package.json 快速入门教程 2017年08月02日 19:16:20 阅读数:33887 npm 是前端开发广泛使用的包管理工具,之前使用 Weex 时看了阮一峰前辈的文章了解 ...

  3. go多进程

    package main import "fmt" import "time"func loop() { for i := 0; i < 10; i++ ...

  4. php settype()和gettype()

    gettype()是获得变量的类型,settype()函数用来配置或转换变量类型.成功返回 true 值,其它情形返回 false 值.参数 var 为原来的变量名,参数 type 为下列的类型之一: ...

  5. 【Kafka】《Kafka权威指南》——从Kafka读取数据

    应用程序使用 KafkaConsumer向 Kafka 订阅主题,并从订阅的主题上接收消息 . 从 Kafka 读取数据不同于从其他悄息系统读取数据,它涉及一些独特的概念和想法.如果不先理解 这些概念 ...

  6. 微信小程序商品展示页面(仿咸鱼)

    项目中做了一个商品发布展示的页面,记录下来 解决问题: 想在setData中更改数组具体下标中的某个值: let one = "lowMoney[" + 0 + "].m ...

  7. MySQL数据库笔记总结

    MySQL数据库总结 一.数据库简介 1. 数据 所谓数据(Data)是指对客观事物进行描述并可以鉴别的符号,这些符号是可识别的.抽象的.它不仅仅指狭义上的数字,而是有多种表现形式:字母.文字.文本. ...

  8. nodejs全局安装路径的位置

    一般nodejs安装在默认的C盘,如果不知道安装在哪里,可以打开控制面板-系统和安全-系统-高级配置中找到 所谓全局安装: 是指安装在node中node_module的根目录里,可以在电脑的任何位置调 ...

  9. 忘记Oracle密码

    1./as sysdba 2.然后你忘记密码的用户名例如Scott alter user scott identified by root 3.exit 4.sqlplus 重新登录

  10. JS高级——函数的调用模式

    函数调用模式一共有四种 <script> //1.函数模式 //this指向window全局对象 //2.方法模式 //this指向调用这个方法的对象 //3.构造函数模式 //this ...